前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java中TCP通信的实现

Java中TCP通信的实现

作者头像
头发还在
发布2023-10-16 11:01:32
1820
发布2023-10-16 11:01:32
举报
文章被收录于专栏:桃花源

0、TCP通信

传输控制协议(TCP,Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议,

如果使用了 WireShark 工具,可以看到一次TCP连接建立时的整个过程。

1、单向通信

单向通信中,一方固定为信息发送方,另外一方则固定为信息的接收方。

1.1 单向通信中的服务端

服务端即为信息的接收方。

使用 ServerSocket 类创建服务端,并将服务的端口设置为 9527;

serverSocket.accept() 方法用于监听对 9527 端口的连接,该方法为阻塞式方法,当接收到数据后,程序才会继续向下执行,否则一直处于等待状态;

当接收到数据后,因是使用字节流传输,这里使用 使用 InputStreamReader 的转换流将字节数据转换为字符串,并使用 BufferedReader 进行读取和输出;

当服务端接收到客户端的请求后,需要向客户端发出响应数据,使用 PrintWriter 发送响应报文,需要使用 flush() 方法,将消息发出;

当客户端发出的消息为“再见”时,服务端即退出通信,关闭服务。

代码语言:javascript
复制
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {
    public static void main(String[] args) {
        System.out.println("服务器启动!");
        try {
            ServerSocket serverSocket = new ServerSocket(9527);
            Socket socket = serverSocket.accept();
            BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            PrintWriter pw = new PrintWriter(socket.getOutputStream());
            System.out.println("接收客户端消息");

            while (true){
                String in = br.readLine();
                System.out.println("接收到客户端发来的请求:" + in);
                if("再见".equals(in)){
                    break;
                }
                pw.print(in + "回报");
                pw.flush();
            }
        } catch (IOException e) {
            System.out.println("服务启动失败!");
            e.printStackTrace();
        }
    }
}

启动后,服务端输出为:

服务器启动!

1.2 单向通信中的客户端

客户端即为信息的发送方。

  • 创建 Socket 对象,​​Socket("localhost", 9527)​​ 和端口为 9527 的服务建立通信;
  • 接收和发送消息的方法,和服务端相同;
  • 为了能够向服务端循环发送消息,使用了死循环,当用户输入“再见”时,终止循环;
  • 使用 Scanner 对象接收键盘输入。
代码语言:javascript
复制
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;

public class Client {
    public static void main(String[] args) {
        try {
            Socket socket = new Socket("localhost", 9527);
            //读取输入流
            BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            //获取输出流
            PrintWriter pw = new PrintWriter(socket.getOutputStream());
            //从键盘获取输入
            Scanner scanner = new Scanner(System.in);

            while (true){
                //从控制台获取向服务端发送的消息
                String next = scanner.next();
                pw.println(next);
                pw.flush();

                String s = br.readLine();
                System.out.println("收到服务器响应:" + s);

                if("再见".equals(next)){
                    break;
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

1.3 建立通信

启动客户端后,并在客户端的控制台输入“你好”,观察服务端和客户端的控制台

在客户端的控制台输入“再见”,观察服务端和客户端的控制台

2、双向通信

双向通信中,双方都可以既是信息的发送方,也可以是信息的接收方。

2.1 双向通信中的服务端

在服务端设置发消息和收消息。

在服务端也使用了 Scanner ,用来接收控制台输入,并将其发送给客户端。

代码语言:javascript
复制
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;

public class Server {
    public static void main(String[] args) {
        try{
            ServerSocket serverSocket = new ServerSocket(9528);
            Socket socket = serverSocket.accept();
            //获取客户端请求
            BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            //获取键盘输入
            Scanner scanner = new Scanner(System.in);
            //发送消息到客户端
            PrintWriter pw = new PrintWriter(socket.getOutputStream());

            while (true){
                String input = br.readLine();
                System.out.println("收到客户端请求: " + input);
                String output = scanner.nextLine();

                pw.println(output);
                pw.flush();

                if("再见".equals(input)){
                    break;
                }
            }
        }catch (Exception e){
            e.printStackTrace();
            System.out.println("服务启动失败!");
        }
    }
}

2.2 双向通信中的客户端

在客户端设置发消息和收消息

代码语言:javascript
复制
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;

public class Client {
    public static void main(String[] args) {
        try{
            Socket socket = new Socket("127.0.0.1", 9528);
            //获取服务端响应
            BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            //获取客户端用户输入
            Scanner scanner = new Scanner(System.in);
            //向服务端发送请求
            PrintWriter pw = new PrintWriter(socket.getOutputStream());
            System.out.println("准备接收请求……");
            while (true){
                String output = scanner.next();
                pw.println(output);
                pw.flush();

                String input = br.readLine();
                System.out.println("来自服务端的响应: " + input);
                if("再见".equals(output)){
                    break;
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

2.3 建议通信

启动服务端及客户端,并在控制台输入内容:

存在的问题:

这样的通信,需要客户端发一次消息 -》 服务端回一次消息,如果客户端同时发送两条消息,就会导致消息不同步。

比如下边的情况:

这个问题可以先思考下,应该如何解决,后边将会给出解决方案。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-10-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 0、TCP通信
  • 1、单向通信
    • 1.1 单向通信中的服务端
      • 1.2 单向通信中的客户端
        • 1.3 建立通信
        • 2、双向通信
          • 2.1 双向通信中的服务端
            • 2.2 双向通信中的客户端
              • 2.3 建议通信
              相关产品与服务
              云服务器
              云服务器(Cloud Virtual Machine,CVM)提供安全可靠的弹性计算服务。 您可以实时扩展或缩减计算资源,适应变化的业务需求,并只需按实际使用的资源计费。使用 CVM 可以极大降低您的软硬件采购成本,简化 IT 运维工作。
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档