java网络编程——tcp

java网络编程udp请到java网络编程之udp

tcp协议

  1. TCP是有链接的协议
  2. TCP属于一问一答
  3. TCP有服务器和客户端的概念

编码时:

有两个很重要的对象 :
Scoket:服务端和客户端都要使用,负责传输数据。
ServerSoket:服务端使用,负责接收客户端的连接请求。

其它两个重要的对象:
InputStream:输入流
OutputStream:输出流

例1(发送一句话):

客户端发送一句话给服务器

服务端:

public class TcpServer {
    public static void main(String [] args) throws IOException {
        //1. 创建服务器端Socket
        ServerSocket serverSocket = new ServerSocket(2200);
        // 获取客户端的连接
        Socket socket = serverSocket.accept();
        //2. 获取输入流,这里的流是通过socket拿到的,也属于来自网络
        InputStream inputStream = socket.getInputStream();
        InputStreamReader inputStreamReader = new InputStreamReader(inputStream, StandardCharsets.UTF_8);
        //3. 获取客户端传上来的消息
        char [] message = new char[1024];
        int length = 0;
        if((length = inputStreamReader.read(message)) != -1) {
            String str = new String(message,0,length);
            System.out.println("收到客户端的消息:" + str);
        }
        inputStreamReader.close();
        inputStream.close();
        socket.close();
    }
}

客户端:

public class TcpClient {
    public static void main(String ... args) throws IOException {
        //1. 申明客户端socket对象
        Socket socketClient = new Socket("127.0.0.1",2200);
        //2. 准备要发送的数据
        String message = "你好,服务器,我来了!";
        //3. 发送数据到服务器
        //3.1 获取输出流,这里的输出流其实是网络流。回想一下我们io里的源和目标的类型
        OutputStream outputStream = socketClient.getOutputStream();
        OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream, StandardCharsets.UTF_8);
        //发送数据到服务器
        outputStreamWriter.write(message);
        //关闭流,关闭流也就关闭了和服务器的连接
        outputStreamWriter.close();
        socketClient.close();
        System.out.println("客户端消息发送结束");
    }
}

例2(传文件):

客户端给服务端上传一个图片(可以类比为io流的复制文件操作,吧文件存放位置改为另外一台电脑)

客户端:

public class TcpClient {
    public static void main(String [] args) throws IOException {
        System.out.println("上传客户端启动");
        Socket socketClient = new Socket("127.0.0.1",2200);
        //创建文件输入流
        FileInputStream fileInputStream = new FileInputStream("image/4.jpg");
        // 创建输出流,改输出流将把文件数据输送到服务器上
        OutputStream outputStream = socketClient.getOutputStream();
        int data = 0;
        while((data = fileInputStream.read()) != -1) {
            outputStream.write(data);
        }
        fileInputStream.close();
        outputStream.close();
        socketClient.close();
        System.out.println("客户端退出链接");
    }
}

服务端:

public class TcpServer {
    public static void main(String [] args) throws IOException {
        System.out.println("上传服务器启动");
        ServerSocket serverSocket = new ServerSocket(2200);
        Socket socket = serverSocket.accept();

        // 创建客户端输入流,准备接收客户端上传的文件数据
        InputStream inputStream = socket.getInputStream();
        long currentTime = System.currentTimeMillis();
        // 创建文件输入流,用于保存客户端上传的文件到服务器本地磁盘
        FileOutputStream fileOutputStream = new FileOutputStream("image/" + currentTime +".jpg");
        int data = 0;
        // 通过输入流,读取客户端上传的文件数据
        while((data = inputStream.read()) != -1) {
            // 将文件数据写入到服务的本地磁盘
            fileOutputStream.write(data);
        }
        fileOutputStream.close();
        inputStream.close();
        socket.close();
        System.out.println("服务端接收文件完毕");
    }
}

例3(改进例2):

在例2的基础上,当文件上传完后服务器发送“图片接收完”给客户端。
客户端:

public class TcpClient {
    public static void main(String [] args) throws IOException {
        System.out.println("上传客户端启动");
        Socket socketClient = new Socket("127.0.0.1",2200);
        //创建文件输入流
        FileInputStream fileInputStream = new FileInputStream("image/4.jpg");
        // 创建输出流,改输出流将把文件数据输送到服务器上
        OutputStream outputStream = socketClient.getOutputStream();
        int data = 0;
        while((data = fileInputStream.read()) != -1) {
            outputStream.write(data);
        }
        //shutdownOutput 给服务器一个结束标记,告诉服务器输出操作已经传输完毕,但socket不关闭。
        // 服务器的输入流会接收到这个标记,明白数据传输已经完毕,然后退出while循环。
        socketClient.shutdownOutput();
        System.out.println("本地文件上传结束.. 等待服务器的响应");

        // 创建一个输入流,读取服务器发送的消息
        BufferedReader bufferedReader = new BufferedReader(
                new InputStreamReader(socketClient.getInputStream()));
        String message = bufferedReader.readLine();
        System.out.println("服务器说:" + message);

        fileInputStream.close();
        outputStream.close();
        socketClient.close();
        System.out.println("客户端退出链接");
    }
}

shutdownOutput 给服务器一个结束标记,告诉服务器输出操作已经传输完毕,但socket不关闭。
服务器的输入流会接收到这个标记,明白数据传输已经完毕,然后退出while循环。如果没有这句代码,服务器就不知道客户端的数据传输完成,会一直在while循环中。

服务端:

public class TcpServer {
    public static void main(String [] args) throws IOException {
        System.out.println("上传服务器启动");
        ServerSocket serverSocket = new ServerSocket(2200);
        Socket socket = serverSocket.accept();

        // 创建客户端输入流,准备接收客户端上传的文件数据
        InputStream inputStream = socket.getInputStream();
        long currentTime = System.currentTimeMillis();
        // 创建文件输入流,用于保存客户端上传的文件到服务器本地磁盘
        FileOutputStream fileOutputStream = new FileOutputStream("image/" + currentTime +".jpg");
        int data = 0;
        // 通过输入流,读取客户端上传的文件数据
        while((data = inputStream.read()) != -1) {
            // 将文件数据写入到服务的本地磁盘
            fileOutputStream.write(data);
        }
        System.out.println("服务器保存文件结束,开始发送文件上传完毕的消息给客户端");
        //创建一个输出流,用于向客户端输出消息
        BufferedWriter bufferedWriter = new BufferedWriter(
                new OutputStreamWriter(socket.getOutputStream()));

        bufferedWriter.write("文件上传完毕");
        bufferedWriter.close();
        // 改进:文件上传完毕,给客户端发送一条消息
        fileOutputStream.close();
        inputStream.close();
        socket.close();
        System.out.println("服务端接收文件完毕");
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值