javaSE第二十六天

第二十六天    414

1:网络编程(理解)    414

(1)网络编程:用Java语言实现计算机间数据的信息传递和资源共享    414

(2)网络编程模型    414

(3)网络编程的三要素    414

(4)网络编程中主要类介绍:    416

A:InetAddress: 此类表示互联网协议 (IP) 地址。    416

B:    UDP协议下的Socket对象类DatagramSocket    418

1.发送端:    418

2.接收端:    419

C:    TCP协议下的主要类介绍:    420

(5)Socket机制    423

(4)UDP协议发送和接收数据(掌握)    423

1.原理图解    423

2.发送:步骤    423

3.接收:步骤    424

(5)TCP协议发送和接收数据(掌握)    425

A:原理图解    425

2.发送:步骤    425

3.接收:步骤    427

(6)案例:    427

A:UDP    428

a:最基本的UDP协议发送和接收数据    428

b:把发送数据改进为键盘录入    429

c:一个简易聊天小程序并用多线程改进    431

B:TCP    433

a: 服务器给出反馈    433

c:客户端键盘录入服务器控制台输出    435

d:客户端键盘录入服务器写到文本文件    437

e:客户端读取文本文件服务器控制台输出    438

f:客户端读取文本文件服务器写到文本文件    440

g:上传图片    443

h:多线程改进上传文件    445

 

 

 

第二十六天

1:网络编程(理解)
    (1)网络编程:用Java语言实现计算机间数据的信息传递和资源共享
    (2)网络编程模型

    (3)网络编程的三要素

        A:IP地址

            a:点分十进制

            b:IP地址的组成

            c:IP地址的分类

            d:dos命令

            e:InetAddress

        B:端口

            是应用程序的标识。范围:0-65535。其中0-1024不建议使用。

        C:协议

            UDP:数据打包,有限制,不连接,效率高,不可靠

            TCP:建立数据通道,无限制,效率低,可靠

/*

* 网络编程三要素:

    A:IP地址

    B:端口

    C:协议

    

举例:

    我想和林青霞说话了。肿么办?

    A:我要找到林青霞。

    B:对她说话,要对耳朵说。

    C:我说什么呢?"I Love You"

     但是,她没学过英语,听不懂。

     我没必要说英语,说汉语就可以了:我爱你

    

IP地址:

    网络中计算机的唯一标识。

    

    计算机只能识别二进制的数据,所以我们的IP地址应该是一个二进制的数据。

    但是呢,我们配置的IP地址确不是二进制的,为什么呢?

        IP192.168.1.100

        换算:11000000 10101000 00000001 01100100

    假如真是:11000000 10101000 00000001 01100100的话。

    我们如果每次再上课的时候要配置该IP地址,记忆起来就比较的麻烦。

    所以,为了方便表示IP地址,我们就把IP地址的每一个字节上的数据换算成十进制,然后用.分开来表示:

        "点分十进制"

        

    IP地址的组成:网络号段+主机号段

        A类:第一号段为网络号段+后三段的主机号段

            一个网络号:256*256*256 = 16777216

        B类:前二号段为网络号段+后二段的主机号段

            一个网络号:256*256 = 65536

        C类:前三号段为网络号段+后一段的主机号段

            一个网络号:256

    

    IP地址的分类:

        A    1.0.0.1---127.255.255.254    (1)10.X.X.X是私有地址(私有地址就是在互联网上不使用,而被用在局域网络中的地址)                            (2)127.X.X.X是保留地址,用做循环测试用的。

        B    128.0.0.1---191.255.255.254    172.16.0.0---172.31.255.255是私有地址。169.254.X.X是保留地址。

        C    192.0.0.1---223.255.255.254    192.168.X.X是私有地址

        D    224.0.0.1---239.255.255.254     

        E    240.0.0.1---247.255.255.254

        

    两个DOS命令:

        ipconfig 查看本机ip地址

        ping 后面跟ip地址。测试本机与指定的ip地址间的通信是否有问题

        

    特殊的IP地址:

        127.0.0.1 回环地址(表示本机)

        x.x.x.255 广播地址

        x.x.x.0 网络地址

        

端口号:

    正在运行的程序的标识。

    有效端口:0~65535,其中0~1024系统使用或保留端口。

    

协议:

    通信的规则

    

    UDP

        把数据打包

        数据有限制

        不建立连接

        速度快

        不可靠

    

    TCP

        建立连接通道

        数据无限制

        速度慢

        可靠

    

    举例:

        UDP:发短信

        TCP:打电话

*/

 

    (4)网络编程中主要类介绍:

        A:InetAddress: 此类表示互联网协议 (IP) 地址。

            构造方法

            public static InetAddress getByName(String host)根据主机名或者ip地址

            的字符串表现形式创建IP地址对象

            普通方法

            public String getHostName()获取主机名

            public String getHostAddress():获取IP地址

            案例演示:

import java.net.InetAddress;

import java.net.UnknownHostException;

 

/*

* 如果一个类没有构造方法:

* A:成员全部是静态的(Math,Arrays,Collections)

* B:单例设计模式(Runtime)

* C:类中有静态方法返回该类的对象(InetAddress)

*         class Demo {

*             private Demo(){}

*

*             public static Demo getXxx() {

*                 return new Demo();

*             }

*         }

*

* IP地址类:InetAddress的成员方法:

* public static InetAddress getByName(String host):

*                     根据主机名或者IP地址的字符串表示得到IP地址对象

*

*         普通方法:

*          public String getHostName():获取该IP地址对象的主机名

*          public String getHostAddress():获取主机IP地址

*/

public class InetAddressDemo {

    public static void main(String[] args) throws UnknownHostException {

        // public static InetAddress getByName(String host)

        // InetAddress address = InetAddress.getByName("liuyi");

        // InetAddress address = InetAddress.getByName("192.168.12.92");

        InetAddress address = InetAddress.getByName("asus");

 

        // 获取两个东西:主机名,IP地址

        // public String getHostName()

        String name = address.getHostName();

        // public String getHostAddress()

        String ip = address.getHostAddress();

        System.out.println(name + "---" + ip);

    }

}

 

      

        B:    UDP协议下的Socket对象类DatagramSocket

            1.发送端:

 

import java.io.IOException;

import java.net.DatagramPacket;

import java.net.DatagramSocket;

import java.net.InetAddress;

/*

* UDP协议发送数据:

* A:创建发送端Socket对象

* B:创建数据,并把数据打包

* C:调用Socket对象的发送方法发送数据包

* D:释放资源

*

* 说明:UDP协议下的接收端和发送端的Socket对象都是同一个类DatagramSocket

*     

*     DatagramSocket类的方法:

*         构造方法:public DatagramSocket()

*         普通方法:public void send(DatagramPacket p):

*                 从此套接字发送数据报包

*              public void close()

*                 关闭此数据报套接字。

*              public synchronized void receive(DatagramPacket p)

*                  从此套接字接收数据报包。

*                 

*     DatagramPacket数据包类:

*         构造方法:public DatagramPacket(byte buf[], int length,

InetAddress address, int port)

构造数据报包,用来将长度为 length 的包发送到指定主机上的指定端口号    

 

public DatagramPacket(byte buf[], int length)

        构造 DatagramPacket,用来接收长度为 length 的数据包

 

public synchronized InetAddress getAddress()

                返回某台机器的 IP 地址对象

                  

public synchronized byte[] getData():返回数据缓冲区

public synchronized int getLength():返回将要发送或接收到的数据的长度

*/

public class SendDemo {

    public static void main(String[] args) throws IOException {

        // 创建发送端Socket对象

        // DatagramSocket()

        DatagramSocket ds = new DatagramSocket();

 

        // 创建数据,并把数据打包

        // DatagramPacket(byte[] buf, int length, InetAddress address, int port)

        // 创建数据

        byte[] bys = "hello,udp,我来了".getBytes();

        // 长度

        int length = bys.length;

        // IP地址对象

        InetAddress address = InetAddress.getByName("192.168.12.92");

        // 端口

        int port = 10086;

        DatagramPacket dp = new DatagramPacket(bys, length, address, port);

 

        // 调用Socket对象的发送方法发送数据包

        // public void send(DatagramPacket p)

        ds.send(dp);

 

        // 释放资源

        ds.close();

    }

}

 

            2.接收端:

import java.io.IOException;

import java.net.DatagramPacket;

import java.net.DatagramSocket;

import java.net.InetAddress;

 

/*

* UDP协议接收数据:

* A:创建接收端Socket对象

* B:创建一个数据包(接收容器)

* C:调用Socket对象的接收方法接收数据

* D:解析数据包,并显示在控制台

* E:释放资源

*/

public class ReceiveDemo {

    public static void main(String[] args) throws IOException {

        // 创建接收端Socket对象

        // DatagramSocket(int port)

        DatagramSocket ds = new DatagramSocket(10086);

 

        // 创建一个数据包(接收容器)

        // DatagramPacket(byte[] buf, int length)

        byte[] bys = new byte[1024];

        int length = bys.length;

        DatagramPacket dp = new DatagramPacket(bys, length);

 

        // 调用Socket对象的接收方法接收数据

        // public void receive(DatagramPacket p)

        ds.receive(dp); // 阻塞式

 

        // 解析数据包,并显示在控制台

        // 获取对方的ip

        // public InetAddress getAddress()

        InetAddress address = dp.getAddress();

        String ip = address.getHostAddress();

        // public byte[] getData():获取数据缓冲区

        // public int getLength():获取数据的实际长度

        byte[] bys2 = dp.getData();

        int len = dp.getLength();

        String s = new String(bys2, 0, len);

        System.out.println(ip + "传递的数据是:" + s);

 

        // 释放资源

        ds.close();

    }

}

 

        C:    TCP协议下的主要类介绍:

            客户端的主要类Socket

                构造方法

public Socket(String host, int port)创建一个流套接字并将其连接到指定主机上的指定端口号。

普通方法:

public OutputStream getOutputStream()返回此套接字的输出流。

public InputStream getInputStream()返回此套接字的输入流

 

public synchronized void close()关闭此套接字

 

            服务器端的主要类ServerSocket

                构造方法

                public ServerSocket(int port)创建绑定到特定端口的服务器套接字

 

                普通方法

                public Socket accept()侦听并接受到此套接字的连接

                

                案例演示:

                1.客户端:

import java.io.IOException;

import java.io.InputStream;

import java.io.OutputStream;

import java.net.Socket;

 

/*

* TCP协议发送数据:

* A:创建发送端的Socket对象

*         这一步如果成功,就说明连接已经建立成功了。

* B:获取输出流,写数据

* C:释放资源

*

*     TCP协议下的套接字类:

*         套接字类:发送端的socket

*             构造方法:public Socket(String host, int port)

*                     创建一个流套接字并将其连接到指定主机上的指定端口号。

*             普通方法:

*             public OutputStream getOutputStream()

*                                 返回此套接字的输出流。

*             public InputStream getInputStream()

*                                 返回此套接字的输入流

*

*             public synchronized void close():关闭此套接字

*

*

* 连接被拒绝。TCP协议一定要先看服务器。

* java.net.ConnectException: Connection refused: connect

*/

public class ClientDemo {

    public static void main(String[] args) throws IOException {

        // 创建发送端的Socket对象

        // Socket(InetAddress address, int port)

        // Socket(String host, int port)

        // Socket s = new Socket(InetAddress.getByName("192.168.12.92"), 8888);

        Socket s = new Socket("192.168.12.92", 8888);

 

        // 获取输出流,写数据

        // public OutputStream getOutputStream()

        OutputStream os = s.getOutputStream();

        os.write("hello,tcp,我来了".getBytes());

 

        // 释放资源

        s.close();

    }

}

 

                2.服务器端:                

import java.io.IOException;

import java.io.InputStream;

import java.net.ServerSocket;

import java.net.Socket;

 

/*

* TCP协议接收数据:

* A:创建接收端的Socket对象

* B:监听客户端连接。返回一个对应的Socket对象

* C:获取输入流,读取数据显示在控制台

* D:释放资源

*

* 服务器端的套接字类:ServerSocket

*         构造方法:

*         public ServerSocket(int port):创建绑定到特定端口的服务器套接字

*

*         普通方法:

*         public Socket accept():侦听并接受到此套接字的连接

* 说明:不应该关闭服务器端的套接字连接

*/

public class ServerDemo {

    public static void main(String[] args) throws IOException {

        // 创建接收端的Socket对象

        // ServerSocket(int port)

        ServerSocket ss = new ServerSocket(8888);

 

        // 监听客户端连接。返回一个对应的Socket对象

        // public Socket accept()

        Socket s = ss.accept(); // 侦听并接受到此套接字的连接。此方法在连接传入之前一直阻塞。

 

        // 获取输入流,读取数据显示在控制台

        InputStream is = s.getInputStream();

 

        byte[] bys = new byte[1024];

        int len = is.read(bys); // 阻塞式方法

        String str = new String(bys, 0, len);

 

        String ip = s.getInetAddress().getHostAddress();

 

        System.out.println(ip + "---" + str);

 

        // 释放资源

        s.close();

        // ss.close(); //这个不应该关闭

    }

}

 

    (5)Socket机制

        A:通信两端都应该有Socket对象

        B:所有的通信都是通过Socket间的IO进行操作的

    (4)UDP协议发送和接收数据(掌握)

        1.原理图解

        2.发送:步骤

            A:创建UDP发送端的Socket对象

            B:创建数据并把数据打包

            C:发送数据

            D:释放资源

import java.io.IOException;

import java.net.DatagramPacket;

import java.net.DatagramSocket;

import java.net.InetAddress;

/*

* 发送端:

*/

public class SendDemo {

    public static void main(String[] args) throws IOException {

        // 创建发送端的Socket对象

        DatagramSocket ds = new DatagramSocket();

 

        // 创建数据并打包

        byte[] bys = "helloworld".getBytes();

        DatagramPacket dp = new DatagramPacket(bys, bys.length,

                InetAddress.getByName("192.168.12.92"), 12345);

 

        // 发送数据

        ds.send(dp);

 

        // 释放资源

        ds.close();

    }

}

 

            

        3.接收:步骤

            A:创建UDP接收端的Socket对象

            B:创建数据包用于接收数据

            C:接收数据

            D:解析数据包

            E:释放资源

/*

* 多次启动接收端:

*         java.net.BindException: Address already in use: Cannot bind

*         端口被占用。

*/

public class ReceiveDemo {

    public static void main(String[] args) throws IOException {

        // 创建接收端的Socket对象

        DatagramSocket ds = new DatagramSocket(12345);

 

        // 创建一个包裹

        byte[] bys = new byte[1024];

        DatagramPacket dp = new DatagramPacket(bys, bys.length);

 

        // 接收数据

        ds.receive(dp);

 

        // 解析数据

        String ip = dp.getAddress().getHostAddress();

        String s = new String(dp.getData(), 0, dp.getLength());

        System.out.println("from " + ip + " data is : " + s);

 

        // 释放资源

        ds.close();

    }

}

 

    (5)TCP协议发送和接收数据(掌握)

        A:原理图解

        

 

        2.发送:步骤

            a.创建TCP客户端的Socket对象

            b.获取输出流,写数据

            c.释放资源

import java.io.IOException;

import java.io.InputStream;

import java.io.OutputStream;

import java.net.Socket;

/*

* 客户端:

*/

public class ClientDemo {

    public static void main(String[] args) throws IOException {

        // 创建客户端Socket对象

        Socket s = new Socket("192.168.12.92", 9999);

 

        // 获取输出流

        OutputStream os = s.getOutputStream();

        os.write("今天天气很好,适合睡觉".getBytes());

 

        // 获取输入流

        InputStream is = s.getInputStream();

        byte[] bys = new byte[1024];

        int len = is.read(bys);// 阻塞

        String client = new String(bys, 0, len);

        System.out.println("client:" + client);

 

        // 释放资源

        s.close();

    }

}

 

            

        3.接收:步骤

            A:创建TCP服务器端的Socket对象

            B:监听客户端连接

            C:获取输入流,读取数据

            D:释放资源

import java.io.IOException;

import java.io.InputStream;

import java.io.OutputStream;

import java.net.ServerSocket;

import java.net.Socket;

/*

* 服务器端:

*/

public class ServerDemo {

    public static void main(String[] args) throws IOException {

        // 创建服务器Socket对象

        ServerSocket ss = new ServerSocket(9999);

 

        // 监听客户端的连接

        Socket s = ss.accept(); // 阻塞

 

        // 获取输入流

        InputStream is = s.getInputStream();

        byte[] bys = new byte[1024];

        int len = is.read(bys); // 阻塞

        String server = new String(bys, 0, len);

        System.out.println("server:" + server);

 

        // 获取输出流

        OutputStream os = s.getOutputStream();

        os.write("数据已经收到".getBytes());

 

        // 释放资源

        s.close();

        // ss.close();

    }

}

 

    (6)案例:

        A:UDP

            a:最基本的UDP协议发送和接收数据

            1.发送端

import java.io.IOException;

import java.net.DatagramPacket;

import java.net.DatagramSocket;

import java.net.InetAddress;

/*

* 发送端:

*/

public class SendDemo {

    public static void main(String[] args) throws IOException {

        // 创建发送端的Socket对象

        DatagramSocket ds = new DatagramSocket();

 

        // 创建数据并打包

        byte[] bys = "helloworld".getBytes();

        DatagramPacket dp = new DatagramPacket(bys, bys.length,

                InetAddress.getByName("192.168.12.92"), 12345);

 

        // 发送数据

        ds.send(dp);

 

        // 释放资源

        ds.close();

    }

}

 

 

            2.接收端:

import java.io.IOException;

import java.net.DatagramPacket;

import java.net.DatagramSocket;

 

/*

* 多次启动接收端:

*         java.net.BindException: Address already in use: Cannot bind

*         端口被占用。

*/

public class ReceiveDemo {

    public static void main(String[] args) throws IOException {

        // 创建接收端的Socket对象

        DatagramSocket ds = new DatagramSocket(12345);

 

        // 创建一个包裹

        byte[] bys = new byte[1024];

        DatagramPacket dp = new DatagramPacket(bys, bys.length);

 

        // 接收数据

        ds.receive(dp);

 

        // 解析数据

        String ip = dp.getAddress().getHostAddress();

        String s = new String(dp.getData(), 0, dp.getLength());

        System.out.println("from " + ip + " data is : " + s);

 

        // 释放资源

        ds.close();

    }

}

 

            b:把发送数据改进为键盘录入

            1.发送端

import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStreamReader;

import java.net.DatagramPacket;

import java.net.DatagramSocket;

import java.net.InetAddress;

 

/*

* 需求:数据来自于键盘录入

* 键盘录入数据要自己控制录入结束。

*/

public class SendDemo {

    public static void main(String[] args) throws IOException {

        // 创建发送端的Socket对象

        DatagramSocket ds = new DatagramSocket();

 

        // 封装键盘录入数据

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        String line = null;

        while ((line = br.readLine()) != null) {

            if ("886".equals(line)) {

                break;

            }

 

            // 创建数据并打包

            byte[] bys = line.getBytes();

            // DatagramPacket dp = new DatagramPacket(bys, bys.length,

            // InetAddress.getByName("192.168.12.92"), 12345);

            DatagramPacket dp = new DatagramPacket(bys, bys.length,

                    InetAddress.getByName("192.168.12.255"), 12345);

 

            // 发送数据

            ds.send(dp);

        }

 

        // 释放资源

        ds.close();

    }

}

 

 

            2.接收端:

import java.io.IOException;

import java.net.DatagramPacket;

import java.net.DatagramSocket;

 

/*

* 多次启动接收端:

*         java.net.BindException: Address already in use: Cannot bind

*         端口被占用。

*/

public class ReceiveDemo {

    public static void main(String[] args) throws IOException {

        // 创建接收端的Socket对象

        DatagramSocket ds = new DatagramSocket(12345);

 

        while (true) {

            // 创建一个包裹

            byte[] bys = new byte[1024];

            DatagramPacket dp = new DatagramPacket(bys, bys.length);

 

            // 接收数据

            ds.receive(dp);

 

            // 解析数据

            String ip = dp.getAddress().getHostAddress();

            String s = new String(dp.getData(), 0, dp.getLength());

            System.out.println("from " + ip + " data is : " + s);

        }

 

        // 释放资源

        // 接收端应该一直开着等待接收数据,是不需要关闭

        // ds.close();

    }

}

 

 

            c:一个简易聊天小程序并用多线程改进

            1.发送端,实现多线程

import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStreamReader;

import java.net.DatagramPacket;

import java.net.DatagramSocket;

import java.net.InetAddress;

/*

* 发送端:实现多线程

*/

public class SendThread implements Runnable {

 

    private DatagramSocket ds;

 

    public SendThread(DatagramSocket ds) {

        this.ds = ds;

    }

 

    @Override

    public void run() {

        try {

            // 封装键盘录入数据

            BufferedReader br = new BufferedReader(new InputStreamReader(

                    System.in));

            String line = null;

            while ((line = br.readLine()) != null) {

                if ("886".equals(line)) {

                    break;

                }

 

                // 创建数据并打包

                byte[] bys = line.getBytes();

                // DatagramPacket dp = new DatagramPacket(bys, bys.length,

                // InetAddress.getByName("192.168.12.92"), 12345);

                DatagramPacket dp = new DatagramPacket(bys, bys.length,

                        InetAddress.getByName("192.168.12.255"), 12306);

 

                // 发送数据

                ds.send(dp);

            }

 

            // 释放资源

            ds.close();

        } catch (IOException e) {

            e.printStackTrace();

        }

    }

 

}

 

 

            2.接收端,实现多线程

import java.io.IOException;

import java.net.DatagramPacket;

import java.net.DatagramSocket;

/*

*接收端:实现多线程

*/

public class ReceiveThread implements Runnable {

    private DatagramSocket ds;

 

    public ReceiveThread(DatagramSocket ds) {

        this.ds = ds;

    }

 

    @Override

    public void run() {

        try {

            while (true) {

                // 创建一个包裹

                byte[] bys = new byte[1024];

                DatagramPacket dp = new DatagramPacket(bys, bys.length);

 

                // 接收数据

                ds.receive(dp);

 

                // 解析数据

                String ip = dp.getAddress().getHostAddress();

                String s = new String(dp.getData(), 0, dp.getLength());

                System.out.println("from " + ip + " data is : " + s);

            }

        } catch (IOException e) {

            e.printStackTrace();

        }

    }

 

}

 

            3.测试类

import java.io.IOException;

import java.net.DatagramSocket;

 

/*

* 测试类:通过多线程改进刚才的聊天程序,这样我就可以实现在一个窗口发送和接收数据了

*/

public class ChatRoom {

    public static void main(String[] args) throws IOException {

        //创建发送端Socket对象

        DatagramSocket dsSend = new DatagramSocket();

        //创建接收端Socket对象

        DatagramSocket dsReceive = new DatagramSocket(12306);

        //创建发送线程对象

        SendThread st = new SendThread(dsSend);

        //创建接收线程对象

        ReceiveThread rt = new ReceiveThread(dsReceive);

 

        Thread t1 = new Thread(st);

        Thread t2 = new Thread(rt);

        //启动线程

        t1.start();

        t2.start();

    }

}

 

        B:TCP

            a: 服务器给出反馈

            1.客户端

import java.io.IOException;

import java.io.InputStream;

import java.io.OutputStream;

import java.net.Socket;

/*

* 客户端:

*/

public class ClientDemo {

    public static void main(String[] args) throws IOException {

        // 创建客户端Socket对象

        Socket s = new Socket("192.168.12.92", 9999);

 

        // 获取输出流

        OutputStream os = s.getOutputStream();

        os.write("今天天气很好,适合睡觉".getBytes());

 

        // 获取输入流

        InputStream is = s.getInputStream();

        byte[] bys = new byte[1024];

        int len = is.read(bys);// 阻塞

        String client = new String(bys, 0, len);

        System.out.println("client:" + client);

 

        // 释放资源

        s.close();

    }

}

 

 

            2.服务器端:

import java.io.IOException;

import java.io.InputStream;

import java.io.OutputStream;

import java.net.ServerSocket;

import java.net.Socket;

/*

* 服务器端:

*/

public class ServerDemo {

    public static void main(String[] args) throws IOException {

        // 创建服务器Socket对象

        ServerSocket ss = new ServerSocket(9999);

 

        // 监听客户端的连接

        Socket s = ss.accept(); // 阻塞

 

        // 获取输入流

        InputStream is = s.getInputStream();

        byte[] bys = new byte[1024];

        int len = is.read(bys); // 阻塞

        String server = new String(bys, 0, len);

        System.out.println("server:" + server);

 

        // 获取输出流

        OutputStream os = s.getOutputStream();

        os.write("数据已经收到".getBytes());

 

        // 释放资源

        s.close();

        // ss.close();

    }

}

 

 

            c:客户端键盘录入服务器控制台输出

            1.客户端

import java.io.BufferedReader;

import java.io.BufferedWriter;

import java.io.IOException;

import java.io.InputStreamReader;

import java.io.OutputStreamWriter;

import java.net.Socket;

 

/*

* 需求:客户端键盘录入,服务器输出到控制台

*/

public class ClientDemo {

    public static void main(String[] args) throws IOException {

        // 创建客户端Socket对象

        Socket s = new Socket("127.0.0.1", 22223);

 

        // 键盘录入数据

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        // 把通道内的流给包装一下

        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(

                s.getOutputStream()));

 

        String line = null;

        while ((line = br.readLine()) != null) {

            // 键盘录入数据要自定义结束标记

            if ("886".equals(line)) {

                break;

            }

            bw.write(line);

            bw.newLine();

            bw.flush();

        }

 

        // 释放资源

        // bw.close();//不需要关闭

        // br.close();//不需要关闭

        s.close();

    }

}

 

 

            2.服务器端:

import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStreamReader;

import java.net.ServerSocket;

import java.net.Socket;

/*

* 服务器端:

*/

public class ServerDemo {

    public static void main(String[] args) throws IOException {

        // 创建服务器Socket对象

        ServerSocket ss = new ServerSocket(22223);

 

        // 监听客户端连接

        Socket s = ss.accept();

 

        // 包装通道内容的流

        BufferedReader br = new BufferedReader(new InputStreamReader(

                s.getInputStream()));

        String line = null;

        while ((line = br.readLine()) != null) {

            System.out.println(line);

        }

 

        // br.close();

        s.close();

        // ss.close();

    }

}

 

            d:客户端键盘录入服务器写到文本文件

            1.客户端

import java.io.BufferedReader;

import java.io.BufferedWriter;

import java.io.IOException;

import java.io.InputStreamReader;

import java.io.OutputStreamWriter;

import java.net.Socket;

 

/*

* 需求:客户端键盘录入,服务器输出文本文件

*/

public class ClientDemo {

    public static void main(String[] args) throws IOException {

        // 创建客户端Socket对象

        Socket s = new Socket("192.168.12.92", 23456);

 

        // 封装键盘录入

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        // 封装通道内的数据

        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(

                s.getOutputStream()));

 

        String line = null;

        while ((line = br.readLine()) != null) {

            if ("over".equals(line)) {

                break;

            }

 

            bw.write(line);

            bw.newLine();

            bw.flush();

        }

 

        // bw.close();

        // br.close();

        s.close();

    }

}

 

 

            2.服务器端:

import java.io.BufferedReader;

import java.io.BufferedWriter;

import java.io.FileWriter;

import java.io.IOException;

import java.io.InputStreamReader;

import java.net.ServerSocket;

import java.net.Socket;

/*

* 服务器端:

*/

public class ServerDemo {

    public static void main(String[] args) throws IOException {

        // 创建服务器Socket对象

        ServerSocket ss = new ServerSocket(23456);

 

        // 监听客户端连接

        Socket s = ss.accept();

 

        // 封装通道内的数据

        BufferedReader br = new BufferedReader(new InputStreamReader(

                s.getInputStream()));

        // 封装文本文件

        BufferedWriter bw = new BufferedWriter(new FileWriter("a.txt"));

 

        String line = null;

        while ((line = br.readLine()) != null) {

            bw.write(line);

            bw.newLine();

            bw.flush();

        }

 

        bw.close();

        // br.close();

        s.close();

        // ss.close();

    }

}

 

            e:客户端读取文本文件服务器控制台输出

            1.客户端

import java.io.BufferedReader;

import java.io.BufferedWriter;

import java.io.FileReader;

import java.io.IOException;

import java.io.OutputStreamWriter;

import java.net.Socket;

 

/*

* 需求:客户端读取文本文件,服务器输出到控制台

*/

public class ClientDemo {

    public static void main(String[] args) throws IOException {

        // 创建Socket对象

        Socket s = new Socket("192.168.12.92", 34567);

 

        // 封装文本文件

        BufferedReader br = new BufferedReader(new FileReader(

                "InetAddressDemo.java"));

        // 封装通道内的流

        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(

                s.getOutputStream()));

 

        String line = null;

        while ((line = br.readLine()) != null) {

            bw.write(line);

            bw.newLine();

            bw.flush();

        }

 

        br.close();

        s.close();

    }

}

 

 

            2.服务器端:

import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStreamReader;

import java.net.ServerSocket;

import java.net.Socket;

/*

* 服务器端:

*/

public class ServerDemo {

    public static void main(String[] args) throws IOException {

        // 创建服务器Socket对象

        ServerSocket ss = new ServerSocket(34567);

 

        // 监听客户端连接

        Socket s = ss.accept();

 

        // 封装通道内的流

        BufferedReader br = new BufferedReader(new InputStreamReader(

                s.getInputStream()));

 

        String line = null;

        while ((line = br.readLine()) != null) {

            System.out.println(line);

        }

 

        //关闭连接

        s.close();

    }

}

 

            f:客户端读取文本文件服务器写到文本文件

            1.客户端

import java.io.BufferedReader;

import java.io.BufferedWriter;

import java.io.FileReader;

import java.io.IOException;

import java.io.InputStreamReader;

import java.io.OutputStreamWriter;

import java.net.Socket;

 

/*

* 需求:上传一个文件到服务器

*

* 按照我们正常的思路加入反馈信息,结果却没反应。为什么呢?

* 读取文本文件是可以以null作为结束信息的,但是呢,通道内是不能这样结束信息的。

* 所以,服务器根本就不知道你结束了。而你还想服务器给你反馈。所以,就相互等待了。

*

* 如何解决呢?

* A:在多写一条数据,告诉服务器,读取到这条数据说明我就结束,你也结束吧。

*         这样做可以解决问题,但是不好。

* B:Socket对象提供了一种解决方案

*         public void shutdownOutput()

*/

 

public class UploadClient {

    public static void main(String[] args) throws IOException {

        // 创建客户端Socket对象

        Socket s = new Socket("192.168.12.92", 11111);

 

        // 封装文本文件

        BufferedReader br = new BufferedReader(new FileReader(

                "InetAddressDemo.java"));

        // 封装通道内流

        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(

                s.getOutputStream()));

 

        String line = null;

        while ((line = br.readLine()) != null) { // 阻塞

            bw.write(line);

            bw.newLine();

            bw.flush();

        }

        

        //自定义一个结束标记

//        bw.write("over");

//        bw.newLine();

//        bw.flush();

        

        //Socket提供了一个终止,它会通知服务器你别等了,我没有数据过来了

        s.shutdownOutput();

 

        // 接收反馈

        BufferedReader brClient = new BufferedReader(new InputStreamReader(

                s.getInputStream()));

        String client = brClient.readLine(); // 阻塞

        System.out.println(client);

 

        // 释放资源

        br.close();

        s.close();

    }

}

 

 

            2.服务器端:

import java.io.BufferedReader;

import java.io.BufferedWriter;

import java.io.FileWriter;

import java.io.IOException;

import java.io.InputStreamReader;

import java.io.OutputStreamWriter;

import java.net.ServerSocket;

import java.net.Socket;

/*

* 服务器端:

*/

public class UploadServer {

    public static void main(String[] args) throws IOException {

        // 创建服务器端的Socket对象

        ServerSocket ss = new ServerSocket(11111);

 

        // 监听客户端连接

        Socket s = ss.accept();// 阻塞

 

        // 封装通道内的流

        BufferedReader br = new BufferedReader(new InputStreamReader(

                s.getInputStream()));

        // 封装文本文件

        BufferedWriter bw = new BufferedWriter(new FileWriter("Copy.java"));

 

        String line = null;

        while ((line = br.readLine()) != null) { // 阻塞

        // if("over".equals(line)){

        // break;

        // }

            bw.write(line);

            bw.newLine();

            bw.flush();

        }

 

        // 给出反馈

        BufferedWriter bwServer = new BufferedWriter(new OutputStreamWriter(

                s.getOutputStream()));

        bwServer.write("文件上传成功");

        bwServer.newLine();

        bwServer.flush();

 

        // 释放资源

        bw.close();

        s.close();

    }

}

 

            g:上传图片

            1.发送端

import java.io.BufferedInputStream;

import java.io.BufferedOutputStream;

import java.io.FileInputStream;

import java.io.IOException;

import java.io.InputStream;

import java.net.Socket;

/*

* 需求:上传图片

*/

public class UploadClient {

    public static void main(String[] args) throws IOException {

        // 创建客户端Socket对象

        Socket s = new Socket("192.168.12.92", 19191);

 

        // 封装图片文件

        BufferedInputStream bis = new BufferedInputStream(new FileInputStream(

                "林青霞.jpg"));

        // 封装通道内的流

        BufferedOutputStream bos = new BufferedOutputStream(s.getOutputStream());

 

        byte[] bys = new byte[1024];

        int len = 0;

        while ((len = bis.read(bys)) != -1) {

            bos.write(bys, 0, len);

            bos.flush();

        }

        

        s.shutdownOutput();

 

        // 读取反馈

        InputStream is = s.getInputStream();

        byte[] bys2 = new byte[1024];

        int len2 = is.read(bys2);

        String client = new String(bys2, 0, len2);

        System.out.println(client);

 

        // 释放资源

        bis.close();

        s.close();

    }

}

 

 

            2.服务器端:

import java.io.BufferedInputStream;

import java.io.BufferedOutputStream;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.OutputStream;

import java.net.ServerSocket;

import java.net.Socket;

/*

* 服务器端:

*/

public class UploadServer {

    public static void main(String[] args) throws IOException {

        // 创建服务器Socket对象

        ServerSocket ss = new ServerSocket(19191);

 

        // 监听客户端连接

        Socket s = ss.accept();

 

        // 封装通道内流

        BufferedInputStream bis = new BufferedInputStream(s.getInputStream());

        // 封装图片文件

        BufferedOutputStream bos = new BufferedOutputStream(

                new FileOutputStream("mn.jpg"));

 

        byte[] bys = new byte[1024];

        int len = 0;

        //读取文件

        while ((len = bis.read(bys)) != -1) {

            bos.write(bys, 0, len);

            bos.flush();

        }

 

        // 给客户端一个反馈

        OutputStream os = s.getOutputStream();

        os.write("图片上传成功".getBytes());

 

        bos.close();

        s.close();

    }

}

 

            h:多线程改进上传文件

            1.多线程类

import java.io.BufferedReader;

import java.io.BufferedWriter;

import java.io.FileWriter;

import java.io.IOException;

import java.io.InputStreamReader;

import java.io.OutputStreamWriter;

import java.net.Socket;

/*

* 多线程类:

*/

public class UserThread implements Runnable {

    private Socket s;

 

    public UserThread(Socket s) {

        this.s = s;

    }

 

    @Override

    public void run() {

        try {

            // 封装通道内的流

            BufferedReader br = new BufferedReader(new InputStreamReader(

                    s.getInputStream()));

            // 封装文本文件

            // BufferedWriter bw = new BufferedWriter(new

            // FileWriter("Copy.java"));

 

            // 为了防止文件名称冲突

            String newName = System.currentTimeMillis() + ".java";

            BufferedWriter bw = new BufferedWriter(new FileWriter(newName));

 

            String line = null;

            while ((line = br.readLine()) != null) { // 阻塞

                bw.write(line);

                bw.newLine();

                bw.flush();

            }

 

            // 给出反馈

            BufferedWriter bwServer = new BufferedWriter(

                    new OutputStreamWriter(s.getOutputStream()));

            bwServer.write("文件上传成功");

            bwServer.newLine();

            bwServer.flush();

 

            // 释放资源

            bw.close();

            s.close();

        } catch (IOException e) {

            e.printStackTrace();

        }

    }

 

}

 

            2.客户端

import java.io.BufferedReader;

import java.io.BufferedWriter;

import java.io.FileReader;

import java.io.IOException;

import java.io.InputStreamReader;

import java.io.OutputStreamWriter;

import java.net.Socket;

/*

* 需求:多线程上传文件

*/

public class UploadClient {

    public static void main(String[] args) throws IOException {

        // 创建客户端Socket对象

        Socket s = new Socket("192.168.12.92", 11111);

 

        // 封装文本文件

        // BufferedReader br = new BufferedReader(new FileReader(

        // "InetAddressDemo.java"));

        BufferedReader br = new BufferedReader(new FileReader(

                "ReceiveDemo.java"));

        // 封装通道内流

        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(

                s.getOutputStream()));

 

        String line = null;

        while ((line = br.readLine()) != null) { // 阻塞

            bw.write(line);

            bw.newLine();

            bw.flush();

        }

 

        // Socket提供了一个终止,它会通知服务器你别等了,我没有数据过来了

        s.shutdownOutput();

 

        // 接收反馈

        BufferedReader brClient = new BufferedReader(new InputStreamReader(

                s.getInputStream()));

        String client = brClient.readLine(); // 阻塞

        System.out.println(client);

 

        // 释放资源

        br.close();

        s.close();

    }

}

 

 

            3.服务器端:

import java.io.IOException;

import java.net.ServerSocket;

import java.net.Socket;

/*

* 服务器端:

*/

public class UploadServer {

    public static void main(String[] args) throws IOException {

        // 创建服务器Socket对象

        ServerSocket ss = new ServerSocket(11111);

        //循环接收客户端的连接

        while (true) {

            Socket s = ss.accept();

            new Thread(new UserThread(s)).start();

        }

    }

}

 

 

原文地址:https://www.cnblogs.com/Prozhu/p/5874657.html