package com.it.demo01_quickstart;

/*
    案例: 讲解网络编程相关概念.

    网络编程简介:
        概述:
            网络编程也叫: 套接字编程, Socket编程, 就是用来实现 网络互联的 不同计算机上 运行的程序间 可以进行数据交互.
            大白话翻译: 就是用来实现 不同电脑间 进行数据传输的.

        三大要素:
            IP地址:
                概述:
                    设备在网络中的唯一标识.        192.168.37.56
                组成:
                    网络(关)号码 +  主机地址
                分类:
                    城域网: 1 + 3      第一段是网关号码, 后三段是主机地址.
                    广域网: 2 + 2      一般应用于校园网
                    局域网: 3 + 1
                两个DOS指令:
                    ipconfig /all               查看IP
                    ping ip地址/网址 -t         测试网络连接
                两个特殊的IP:
                    127.0.0.1       本地回环(回路)地址, 即: 代表本机.
                    255.255.255.255 广播地址

                InetAddress类:       IP地址的包装类
                    String形式的IP     ->      InetAddress类型的 IP地址对象.
                        public static InetAddress getByName(String ip地址/主机名);       根据字符串形式的ip(或者主机名), 获取其对应的 IP地址对象.

                    InetAddress类型的 IP地址对象       ->   String形式的IP
                        public String getHostAddress();     根据IP地址对象, 获取字符串形式的IP
                        public String getHostName();        根据IP地址对象, 获取字符串形式的 主机名
            端口号:
                概述:
                    程序在设备上的唯一标识.
                范围:
                    0-65535
                注意事项:
                    0-1023之间的端口号不要用, 因为已经被系统占用了或者用作保留端口.
            协议:
                概述:
                    就是设备间传输数据时, 需要遵守的规则, 约定.
                分类:
                    UDP协议:      //类似于: 群聊
                        1. 面向无连接.
                        2. 采用数据报包(DatagramPacket)的形式发送数据, 每个包的大小不能超过64KB.
                        3. 不安全(不可靠)协议.
                        4. 效率相对较高.
                        5. 不区分客户端和服务器端, 叫发送端和接收端.

                    TCP协议:      //类似于: 打电话
                        1. 面向有连接(三次握手)
                        2. 采用IO流的形式发送数据, 理论上来讲无数据大小限制.
                        3. 安全(可靠)协议.
                        4. 效率相对较低.
                        5. 区分客户端和服务器端.

    软件结构:
        常用的软件主要分为: CS结构 和 BS结构
            CS结构:  Client(客户端) 和 Server(服务器端)
                例如: QQ, 微信, LOL

                特点:
                    需求安装客户端, 服务器端升级的时候, 客户端同步也要升级.

                好处:
                    1. 降低服务器压力, 因为可以把一些必要的 大的文件, 提前让用户安装.
                    2. 用户体验较好. 因为一些必要文件已经提前下载好了, 所以此类产品界面一般做的比较好看.

                弊端:
                    当服务器端升级的时候, 客户端同步也要升级.

            BS结构:  Browser(浏览器端) 和 Server(服务器端)
                例如: 天猫, 京东

                特点:
                    无需安装特定软件, 只要有一个浏览器就可以访问.

                好处:
                    1. 更灵活, 用户无需安装特定软件, 只要有一个浏览器就可以访问.
                    2. 用户体验较好, 只要有一个浏览器, 就可以访问了, 无需安装其他软件,
                       也无需定时更新指定的客户端.
                弊端:
                    1. 服务器压力过大, 因为浏览器端所需的所有的数据都会从 服务器端下载.
                    2. 需要用户记忆大量的网址...
 */
public class Demo01 {
    public static void main(String[] args) {

    }
}

 

package com.it.demo02_inetaddress;

import java.net.InetAddress;
import java.net.UnknownHostException;

/*
    案例: 演示InetAddress IP地址包装类.


    InetAddress类的成员方法:       IP地址的包装类
        String形式的IP     ->      InetAddress类型的 IP地址对象.
            public static InetAddress getByName(String ip地址/主机名);       根据字符串形式的ip(或者主机名), 获取其对应的 IP地址对象.

        InetAddress类型的 IP地址对象       ->   String形式的IP
            public String getHostAddress();     根据IP地址对象, 获取字符串形式的IP
            public String getHostName();        根据IP地址对象, 获取字符串形式的 主机名
 */
public class Demo01 {
    public static void main(String[] args) throws UnknownHostException {
        //需求1: String    ->     InetAddress
        //根据ip地址获取,     推荐方式.
        String ip = "192.168.88.5";
        InetAddress inet1 = InetAddress.getByName(ip);
        System.out.println(inet1);      //如果是通过ip获取的 IP对象, 打印的时候只有: ip地址
        System.out.println("---------------------");

        //根据主机名获取, 了解.
        String hostName = "HangGe";
        InetAddress inet2 = InetAddress.getByName(hostName);
        System.out.println(inet2);      //如果是通过 主机名获取的, 打印的时候是: 主机名, ip地址.
        System.out.println("---------------------");


        //需求2: InetAddress  ->  String
        System.out.println(inet1.getHostAddress());     //192.168.88.5
        System.out.println(inet1.getHostName());        //HangGe

    }
}
package com.it.demo03_udp;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.Socket;

/*
    案例: 演示UDP协议发送和接收数据
 */
//接收端.
public class ReceiveDemo {
    public static void main(String[] args) throws Exception {
        //1. 创建接收端的Socket对象, 指定端口号.
        DatagramSocket ds = new DatagramSocket(12345);

        //2. 创建DatagramPacket对象, 用来接收 发送端发过来的数据.
        //                          要装数据的数组       数组的可用长度
        //使用这个构造方法:  DatagramPacket(byte[] buf, int length)
        byte[] bys = new byte[1024];
        DatagramPacket dp = new DatagramPacket(bys, bys.length);

        //3. 通过接收端的Socket对象, 接收发送端发过来的数据, 并存储到 数据报包对象中.
        ds.receive(dp);

        //4. 从数据报包对象中获取数据.
        byte[] data = dp.getData();     //从数据报包对象中获取数据.
        int len = dp.getLength();       //从数据报包对象中获取 具体的有效字节数.
        String s = new String(data, 0, len);

        //5. 打印数据.
        System.out.println(s);

        //6. 关闭接收端的Socket对象.
        ds.close();
    }
}
package com.it.demo03_udp;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

/*
    案例: 演示UDP协议发送和接收数据.

    补充: 网络通信的原理
        网络通信也叫Socket通信, 数据在两个Socket之间通过 数据报包 或者 IO流的形式进行传输.
 */
//发送端.
public class SendDemo {
    public static void main(String[] args) throws Exception {
        //1. 创建发送端的Socket对象.
        DatagramSocket ds = new DatagramSocket();
        //2. 定义要发送的数据.
        String s = "恭喜发财, 红包拿来";
        byte[] bys = s.getBytes();

        //3. 将要发送的数据封装到 数据报包中(DatagramPacket)中.
        //                               要发送的数据  数据长度     接收端的IP地址       端口号
        //使用这个构造方法: DatagramPacket(byte[] buf, int length, InetAddress address, int port)
        DatagramPacket dp = new DatagramPacket(bys, bys.length, InetAddress.getByName("127.0.0.1"), 12345);

        //4. 通过Socket对象, 发送数据报包
        ds.send(dp);

        //5. 关闭Socket对象.
        ds.close();
    }
}
package com.it.demo04_tcp_quickstart;

import java.io.OutputStream;
import java.net.Socket;

/*
    案例: 演示TCP协议之发送数据.

    步骤:
        1. 创建客户端Socket对象, 指定服务器端的ip, 端口号.
        2. 通过 Socket#getOutputStream()方法, 获取输出流, 可以往服务器端写数据.
        3. 通过输出流, 给服务器端写数据.
        4. 关闭Socket对象.
 */

//客户端
public class ClientDemo {
    public static void main(String[] args) throws Exception {
        //1. 创建客户端Socket对象, 指定服务器端的ip, 端口号.
        Socket socket = new Socket("192.168.88.5", 10087);
        //2. 通过 Socket#getOutputStream()方法, 获取输出流, 可以往服务器端写数据.
        OutputStream os = socket.getOutputStream();
        //3. 通过输出流, 给服务器端写数据.
        os.write("Hello, TCP , 我来了!".getBytes());
        //4. 关闭Socket对象.
        socket.close();
    }
}
package com.it.demo04_tcp_quickstart;

import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

/*
    案例: 演示TCP协议之接收数据.

    步骤:
        1. 创建服务器端端Socket对象(ServerSocket), 指定端口号.
        2. 通过ServerSocket#accept()方法监听客户端连接,  如果有客户端申请建立连接,
           服务器端在审核完数据之后, 回自动创建一个Socket对象, 负责和此客户端的交互.
        3. 通过Socket#getInnputStream()获取输入流, 可以读取客户端发过来的数据.
        4. 具体接收数据的动作.
        5. 打印接收到的数据.
        6. 关闭Socket对象, 关闭的是与客户端Socket交互的对象, 而不是ServerSocket.
 */
//服务器端
public class ServerDemo {
    public static void main(String[] args) throws Exception {
        //1. 创建服务器端端Socket对象(ServerSocket), 指定端口号.
        ServerSocket server = new ServerSocket(10087);
        //2. 通过ServerSocket#accept()方法监听客户端连接,  如果有客户端申请建立连接,
        //服务器端在审核完数据之后, 回自动创建一个Socket对象, 负责和此客户端的交互.
        System.out.println(1);
        Socket accept = server.accept();
        System.out.println(2);
        //3. 通过Socket#getInnputStream()获取输入流, 可以读取客户端发过来的数据.
        InputStream is = accept.getInputStream();
        //4. 具体接收数据的动作.
        byte[] bys = new byte[1024];
        int len = is.read(bys);
        String s = new String(bys, 0, len);
        //5. 打印接收到的数据.
        System.out.println(s);
        //6. 关闭Socket对象, 关闭的是与客户端Socket交互的对象, 而不是ServerSocket.
        accept.close();
        //server.close();       服务器端Socket对象一般不关闭.
    }
}
package com.it.demo05_tcp_exercise;

import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

/*
    案例: 演示TCP协议之发送数据.

    步骤:
        1. 创建客户端Socket对象, 指定服务器端的ip, 端口号.
        2. 通过 Socket#getOutputStream()方法, 获取输出流, 可以往服务器端写数据.
        3. 通过输出流, 给服务器端写数据.
        4. 关闭Socket对象.
 */

//客户端
public class ClientDemo {
    public static void main(String[] args) throws Exception {
        //1. 创建客户端Socket对象, 指定服务器端的ip, 端口号.
        Socket socket = new Socket("192.168.88.5", 10087);
        //2. 通过 Socket#getOutputStream()方法, 获取输出流, 可以往服务器端写数据.
        OutputStream os = socket.getOutputStream();
        //3. 通过输出流, 给服务器端写数据.
        os.write("Hello, TCP , 我来了!".getBytes());

        //4. 获取输出流, 可以读取服务器端写过来的数据.
        InputStream is = socket.getInputStream();
        //5. 具体读取数据的操作.
        byte[] bys = new byte[1024];
        int len = is.read(bys);
        String s = new String(bys, 0, len);
        //6. 打印读取到的数据.
        System.out.println(s);


        //7. 关闭Socket对象.
        socket.close();
    }
}

package com.it.demo05_tcp_exercise;

import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

/*
    案例: 演示TCP协议之接收数据.

    步骤:
        1. 创建服务器端端Socket对象(ServerSocket), 指定端口号.
        2. 通过ServerSocket#accept()方法监听客户端连接,  如果有客户端申请建立连接,
           服务器端在审核完数据之后, 回自动创建一个Socket对象, 负责和此客户端的交互.
        3. 通过Socket#getInnputStream()获取输入流, 可以读取客户端发过来的数据.
        4. 具体接收数据的动作.
        5. 打印接收到的数据.
        6. 关闭Socket对象, 关闭的是与客户端Socket交互的对象, 而不是ServerSocket.
 */
//服务器端
public class ServerDemo {
    public static void main(String[] args) throws Exception {
        //1. 创建服务器端端Socket对象(ServerSocket), 指定端口号.
        ServerSocket server = new ServerSocket(10087);
        //2. 通过ServerSocket#accept()方法监听客户端连接,  如果有客户端申请建立连接,
        //服务器端在审核完数据之后, 回自动创建一个Socket对象, 负责和此客户端的交互.
        System.out.println(1);
        Socket accept = server.accept();
        System.out.println(2);
        //3. 通过Socket#getInnputStream()获取输入流, 可以读取客户端发过来的数据.
        InputStream is = accept.getInputStream();
        //4. 具体接收数据的动作.
        byte[] bys = new byte[1024];
        int len = is.read(bys);
        String s = new String(bys, 0, len);
        //5. 打印接收到的数据.
        System.out.println(s);

        //6. 获取输出流, 可以往客户端写数据.
        OutputStream os = accept.getOutputStream();
        //7. 给客户端写的具体的数据(回执信息)
        os.write("数据已收到!".getBytes());

        //8. 关闭Socket对象, 关闭的是与客户端Socket交互的对象, 而不是ServerSocket.
        accept.close();
        //server.close();       服务器端Socket对象一般不关闭.
    }
}
package com.it.demo06_tcp_exercise_upload;

import java.io.*;
import java.net.Socket;

/*
    案例: 客户端给服务器端上传文件.

    思路:
        1. 创建客户端的Socket对象, 指定服务器端的ip, 端口号.
        2. 获取字符缓冲输入流对象, 管理数据源文件.
        3. 通过Socket#getOutputStream()获取输出流, 可以往服务器端写数据.
        4. 具体的IO流操作, 读写数据.
        5. 关流, 释放资源.
 */
//客户端
public class ClientDemo {
    public static void main(String[] args) throws Exception{
        //1. 创建客户端的Socket对象, 指定服务器端的ip, 端口号.
        Socket socket = new Socket("127.0.0.1", 10010);
        //2. 获取字符缓冲输入流对象, 管理数据源文件.
        BufferedReader br = new BufferedReader(new FileReader("D:\\绕口令.txt"));
        //3. 通过Socket#getOutputStream()获取输出流, 可以往服务器端写数据.
        //分解版
        /*OutputStream os = socket.getOutputStream();
        //转换流:  字节流 ->  字符流
        OutputStreamWriter osw = new OutputStreamWriter(os);
        //字符缓冲流: 普通的字符流  ->  高效的字符流
        BufferedWriter bw = new BufferedWriter(osw);*/
        //合并版
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));

        //4. 具体的IO流操作, 读写数据.
        String line;
        while((line = br.readLine()) != null) {
            //把读取到的数据写给服务器端
            bw.write(line);
            bw.newLine();
            bw.flush();     //刷新出 缓冲区中的数据.
        }

        //5. 关流, 释放资源.
        br.close();
        socket.close();
    }
}


package com.it.demo06_tcp_exercise_upload;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;

/*
    案例: 客户端给服务器端上传文件

    思路:
        1. 创建服务器端Socket对象, 指定端口号.
        2. 监听连接.
        3. 创建字符缓冲输出流, 关联目的地文件.
        4. 通过Socket#getInputStream(), 获取输入流, 读取客户端写过来的数据.
        5. 具体的IO流操作, 读写数据.
        6. 关流, 释放资源.
 */
//服务器端
public class ServerDemo {
    public static void main(String[] args) throws Exception{
        // 1. 创建服务器端Socket对象, 指定端口号.
        ServerSocket server = new ServerSocket(10010);
        // 2. 监听连接.
        Socket accept = server.accept();
        // 3. 创建字符缓冲输出流, 关联目的地文件.
        BufferedWriter bw = new BufferedWriter(new FileWriter("day13_socket/data/copy1.txt"));
        // 4. 通过Socket#getInputStream(), 获取输入流, 读取客户端写过来的数据.
        BufferedReader br = new BufferedReader(new InputStreamReader(accept.getInputStream()));
        // 5. 具体的IO流操作, 读写数据.
        String line;
        while((line = br.readLine()) != null) {
            //把读取到的数据写给服务器端
            bw.write(line);
            bw.newLine();
            bw.flush();     //刷新出 缓冲区中的数据.
        }
        // 6. 关流, 释放资源.
        bw.close();
        accept.close();

    }
}
package com.it.demo07_tcp_exercise_upload_message;

import java.io.*;
import java.net.Socket;

/*
    案例: 客户端给服务器端上传文件.

    思路:
        1. 创建客户端的Socket对象, 指定服务器端的ip, 端口号.
        2. 获取字符缓冲输入流对象, 管理数据源文件.
        3. 通过Socket#getOutputStream()获取输出流, 可以往服务器端写数据.
        4. 具体的IO流操作, 读写数据.
        5. 关流, 释放资源.
 */
//客户端
public class ClientDemo {
    public static void main(String[] args) throws Exception{
        //1. 创建客户端的Socket对象, 指定服务器端的ip, 端口号.
        Socket socket = new Socket("127.0.0.1", 10010);
        //2. 获取字符缓冲输入流对象, 管理数据源文件.
        BufferedReader br = new BufferedReader(new FileReader("D:\\绕口令.txt"));
        //3. 通过Socket#getOutputStream()获取输出流, 可以往服务器端写数据.
        //分解版
        /*OutputStream os = socket.getOutputStream();
        //转换流:  字节流 ->  字符流
        OutputStreamWriter osw = new OutputStreamWriter(os);
        //字符缓冲流: 普通的字符流  ->  高效的字符流
        BufferedWriter bw = new BufferedWriter(osw);*/
        //合并版
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));

        //4. 具体的IO流操作, 读写数据.
        System.out.println("client: 1");
        String line;
        while((line = br.readLine()) != null) {
            //把读取到的数据写给服务器端
            bw.write(line);
            bw.newLine();
            bw.flush();     //刷新出 缓冲区中的数据.
        }
        System.out.println("client: 2");

        //5. 核心操作, 客户端上传文件完毕后, 需要给服务器端一个结束标记, 意思是说: 我传完了, 你该干嘛干嘛.
        socket.shutdownOutput();    //给服务器端一个结束标记.

        //6. 获取输入流, 读取服务器端写过来的回执信息.
        BufferedReader br2 = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        //7. 具体接收数据的操作
        System.out.println("client: 3");
        String result = br2.readLine();
        System.out.println("client: 4");
        //8. 打印接收到的数据.
        System.out.println(result);
        //9. 关流, 释放资源.
        br.close();
        socket.close();
    }
}

package com.it.demo07_tcp_exercise_upload_message;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

/*
    案例: 客户端给服务器端上传文件

    思路:
        1. 创建服务器端Socket对象, 指定端口号.
        2. 监听连接.
        3. 创建字符缓冲输出流, 关联目的地文件.
        4. 通过Socket#getInputStream(), 获取输入流, 读取客户端写过来的数据.
        5. 具体的IO流操作, 读写数据.
        6. 关流, 释放资源.
 */
//服务器端
public class ServerDemo {
    public static void main(String[] args) throws Exception {
        // 1. 创建服务器端Socket对象, 指定端口号.
        ServerSocket server = new ServerSocket(10010);
        // 2. 监听连接.
        System.out.println("server: 1");
        Socket accept = server.accept();
        System.out.println("server: 2");
        // 3. 创建字符缓冲输出流, 关联目的地文件.
        BufferedWriter bw = new BufferedWriter(new FileWriter("day13_socket/data/copy1.txt"));
        // 4. 通过Socket#getInputStream(), 获取输入流, 读取客户端写过来的数据.
        BufferedReader br = new BufferedReader(new InputStreamReader(accept.getInputStream()));
        // 5. 具体的IO流操作, 读写数据.
        System.out.println("server: 3");
        String line;
        while ((line = br.readLine()) != null) {
            //把读取到的数据写给服务器端
            bw.write(line);
            bw.newLine();
            bw.flush();     //刷新出 缓冲区中的数据.
        }
        System.out.println("server: 4");

        //6. 获取输出流, 给客户端写回执信息.
        BufferedWriter bw2 = new BufferedWriter(new OutputStreamWriter(accept.getOutputStream()));

        //7. 给客户端写回执信息的具体操作.
        bw2.write("文件上传成功");
        bw2.flush();

        //8.. 关流, 释放资源.
        bw.close();
        accept.close();

    }
}
package com.it.demo08_tcp_upload_thread;

import java.io.*;
import java.net.Socket;

/*
    案例: 客户端给服务器端上传文件.

    思路:
        1. 创建客户端的Socket对象, 指定服务器端的ip, 端口号.
        2. 获取字符缓冲输入流对象, 管理数据源文件.
        3. 通过Socket#getOutputStream()获取输出流, 可以往服务器端写数据.
        4. 具体的IO流操作, 读写数据.
        5. 关流, 释放资源.
 */
//客户端
public class ClientDemo {
    public static void main(String[] args) throws Exception{
        //1. 创建客户端的Socket对象, 指定服务器端的ip, 端口号.
        Socket socket = new Socket("127.0.0.1", 10010);
        //2. 获取字符缓冲输入流对象, 管理数据源文件.
        BufferedReader br = new BufferedReader(new FileReader("D:\\代码打字练习词库.txt"));
        //3. 通过Socket#getOutputStream()获取输出流, 可以往服务器端写数据.
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));

        //4. 具体的IO流操作, 读写数据.
        String line;
        while((line = br.readLine()) != null) {
            //把读取到的数据写给服务器端
            bw.write(line);
            bw.newLine();
            bw.flush();     //刷新出 缓冲区中的数据.
        }

        //5. 核心操作, 客户端上传文件完毕后, 需要给服务器端一个结束标记, 意思是说: 我传完了, 你该干嘛干嘛.
        socket.shutdownOutput();    //给服务器端一个结束标记.

        //6. 获取输入流, 读取服务器端写过来的回执信息.
        BufferedReader br2 = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        //7. 具体接收数据的操作
        String result = br2.readLine();
        //8. 打印接收到的数据.
        System.out.println(result);
        //9. 关流, 释放资源.
        br.close();
        socket.close();
    }
}

package com.it.demo08_tcp_upload_thread;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

/*
    案例: 客户端给服务器端上传文件

    思路:
        1. 创建服务器端Socket对象, 指定端口号.
        2. 监听连接.
        3. 创建字符缓冲输出流, 关联目的地文件.
        4. 通过Socket#getInputStream(), 获取输入流, 读取客户端写过来的数据.
        5. 具体的IO流操作, 读写数据.
        6. 关流, 释放资源.
 */
//服务器端
public class ServerDemo {
    public static void main(String[] args) throws Exception {
        // 1. 创建服务器端Socket对象, 指定端口号.
        ServerSocket server = new ServerSocket(10010);

        //服务器端要不断的监听客户端的连接.
        while(true) {
            // 2. 监听连接.
            Socket accept = server.accept();
            //3. 如果有, 就创建一个线程, 负责和此客户端的交互.
            //new Thread(Runnable接口的子类对象).start();
            new Thread(new ServerThread(accept)).start();
        }

    }
}



package com.it.demo08_tcp_upload_thread;

import java.io.*;
import java.net.Socket;

//自定义的线程资源类, 表示具体的接收文件, 并给出回执信息的动作.
//每一个客户端的Socket对象, 都对应一个服务器端线程(即: ServerThread)
public class ServerThread implements Runnable{
    //定义变量, 表示和客户单Socket通信的 Socket对象.
    private Socket accept;

    public ServerThread(Socket accept) {
        this.accept = accept;
    }

    //具体的接收文件, 并给出回执信息的动作.
    @Override
    public void run() {
        try {
            //解决: 文件重名问题.
            int count = 1;
            File file = new File("day13_socket/data/copy("+ count +").txt");        //copy(1).txt
            while (file.exists()) {
                //走这里, 说明文件存在
                count++;
                file = new File("day13_socket/data/copy("+ count +").txt");         //copy(2).txt, copy(3).txt
            }

            // 3. 创建字符缓冲输出流, 关联目的地文件.
            BufferedWriter bw = new BufferedWriter(new FileWriter(file));
            // 4. 通过Socket#getInputStream(), 获取输入流, 读取客户端写过来的数据.
            BufferedReader br = new BufferedReader(new InputStreamReader(accept.getInputStream()));
            // 5. 具体的IO流操作, 读写数据.
            String line;
            while ((line = br.readLine()) != null) {
                //把读取到的数据写给服务器端
                bw.write(line);
                bw.newLine();
                bw.flush();     //刷新出 缓冲区中的数据.
            }

            //6. 获取输出流, 给客户端写回执信息.
            BufferedWriter bw2 = new BufferedWriter(new OutputStreamWriter(accept.getOutputStream()));

            //7. 给客户端写回执信息的具体操作.
            bw2.write("文件上传成功");
            bw2.flush();

            //8.. 关流, 释放资源.
            bw.close();
            accept.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

 

posted on 2021-01-30 18:48  王平  阅读(74)  评论(0)    收藏  举报