当前位置: 首页 > article >正文

java网络通信(三):TCP通信、实现客户端-服务端消息通信

目录

1、什么是 TCP协议?

2、代码实现TCP协议的一发一收

2.1、客户端

2.2、服务端

2.3 结果演示

3、代码实现TCP协议的多发多收

3.1 客户端

3.2 服务端

3.3 结果演示


简介:本文章主要是演示如何用java代码以及TCP协议实现网络通信,实现客户端给服务端发送消息,服务端接收消息的功能。以及用代码演示如何手动输入消息并发送给服务端(类似聊天软件)。

不了解通信的同学可以先看看我上一篇发的文章,很详细

java网络通信(一):BS架构、CS架构、IP地址、端口号、协议、域名等基础概念,以及代码演示-CSDN博客

1、什么是 TCP协议?

面向连接、可靠通信

三次握手:建立可靠的连接,相当于客户端和服务器生成了一条端对端的管道、可以互相通信。

传输数据时会进行确认,例如客户端发信息给服务端,服务端收到消息后会进行确认,表示已经收到信息。若没有确认,则说明消息服务端并没有收到,则需要客户端再次发送,以此来保证数据传输的可靠性。

四次挥手:在断开连接的时候保证彼此的信息都收发完毕

2、代码实现TCP协议的一发一收

我们的TCP协议实现网络通信中,是端到端的,相当于两个端点形成了一条管道,相互传输数据,十分安全。

2.1、客户端

注意看注释

public class TCP_OneToOne_Clint {
    public static void main(String[] args) throws Exception {
        //1、创建Socket对象,并同时请求于服务端程序的连接
        Socket socket = new Socket("127.0.0.1",8888);

        //2、从socket得到一个字节输出流,用来发送数据给服务端
        OutputStream outputStream = socket.getOutputStream();

        //3、把低级的字节输出流包装成数据输出流
        DataOutputStream dataOutputStream = new DataOutputStream(outputStream);

        //4、开始写数据出去
        dataOutputStream.writeUTF("你好,我是TCP协议客户端发来的消息!");
        System.out.println("我是客户端,已发送消息");
        dataOutputStream.close();

        //5、关闭资源
        socket.close();;
    }
}

2.2、服务端

服务端:serverSocket等待客户端的链接请求,以便建立于客户端的通信管道

accept一但链接成功,就会形成一个可靠的连接通信管道。同时也会返回服务端的socket对象,这样服务端就可以拿到这个socket对象和客户端进行通信了

客户端程序执行到accept的时候,在等待客户端发送请求,一但接收到客户端的请求,就连接成功生成通信管道,且是端到端的,

流的格式一定是客户端和服务端一一对应,通信是非常严格的,否则会出问题。(比如客户端用的是数据流发消息,那么服务端就一定要用数据流读消息)

解释:客户端newSocket的时候,服务端的accept方法就会连接上

public class TCP_OneToOne_Server {

    public static void main(String[] args) throws Exception {
        System.out.println("服务端启动,等待客户端发送消息");
        //1、创建ServerSocket的对象,同时为服务端注册端口
        ServerSocket serverSocket = new ServerSocket(8888);

        //2、使用ServerSocket对象,调用一个accept方法,等待客户端的连接请求
        Socket socket = serverSocket.accept();

        //3、从通信管道中得到一个字节输入流
        InputStream inputStream = socket.getInputStream();

        //4、使用数据输入流包装成输入流(注意必须和客户端的一致)
        DataInputStream dataInputStream = new DataInputStream(inputStream);


          //5、使用数据输入流读取客户端发来的消息
        //当客户端消息还没发来,就会在这一步进行等待(如果客户端先发送信息来,服务端还没读取,没关系,客户端会先把消息缓存起来的
        // 因为是TCP可靠通信,是一定会保证消息被读取的)
        System.out.println(dataInputStream.readUTF());

        //获取客户端的IP地址
        System.out.println(socket.getRemoteSocketAddress());

        //6、关闭资源
        dataInputStream.close();
        socket.close();
    }
}

2.3 结果演示

第一步启动服务端

在客户端还没启动之前,服务端一直在等待客户端的消息

第二步启动客户端:

可以看到客户端将消息发送出去了

再回到服务端看日,可以看到服务端接收到了客户端的消息!

3、代码实现TCP协议的多发多收

3.1 客户端

public class TCP_Many_Clint {

    public static void main(String[] args) throws Exception {
        //1、创建Socket对象,并同时请求于服务端程序的连接
        Socket socket = new Socket("127.0.0.1",8888);

        //2、从socket得到一个字节输出流,用来发送数据给服务端
        OutputStream outputStream = socket.getOutputStream();

        //3、把低级的字节输出流包装成数据输出流
        DataOutputStream dataOutputStream = new DataOutputStream(outputStream);

        Scanner scanner = new Scanner(System.in);
        while (true){
            System.out.println("请说:");
            String msg = scanner.nextLine();
            if ("exit".equals(msg)){
                System.out.println("客户端下线!");
                dataOutputStream.close();
                //5、关闭资源
                socket.close();;
                break;
            }
            dataOutputStream.writeUTF(msg);
            System.out.println("我是客户端,已给服务端发送消息");
        }
    }
}

3.2 服务端

当客户端exit了,服务端就会报错,因为read不到数据了,所以我们可以加一个捕获异常,当读取信息报错时,说明客户端离线了

public class TCP_Many_Server {

    public static void main(String[] args) throws Exception {
        System.out.println("服务端启动,等待客户端发送消息");
        //1、创建ServerSocket的对象,同时为服务端注册端口
        ServerSocket serverSocket = new ServerSocket(8888);

        //2、使用ServerSocket对象,调用一个accept方法,等待客户端的连接请求
        Socket socket = serverSocket.accept();

        //3、从通信管道中得到一个字节输入流
        InputStream inputStream = socket.getInputStream();

        //4、使用数据输入流包装成输入流(注意必须和客户端的一致)
        DataInputStream dataInputStream = new DataInputStream(inputStream);


        while (true){
            try {
                System.out.println(dataInputStream.readUTF());
                System.out.println(socket.getRemoteSocketAddress());
            }catch (Exception e){
                //6、关闭资源
                System.out.println(socket.getRemoteSocketAddress() + "客户端下线!");
                dataInputStream.close();
                socket.close();
                break;
            }
        }
    }
}

3.3 结果演示

第一步启动服务端

在客户端还没启动之前,服务端一直在等待客户端的消息

第二步启动客户端:

输入想要发送的消息。按回车

在服务端就可以看到我们手动在客户端命令行输入的消息了

这就是我对javaTCP通信相关的理解,希望能帮到大家,有问题的地方欢迎大家一起讨论!

后续会不断更新作品,欢迎大家一起讨论学习。❤❤❤


http://www.kler.cn/a/420839.html

相关文章:

  • 【北京迅为】iTOP-4412全能版使用手册-第三十二章 网络通信-TCP套字节
  • Java - JSR223规范解读_在JVM上实现多语言支持
  • 第七课 Unity编辑器创建的资源优化_UI篇(UGUI)
  • 威联通-001 手机相册备份
  • 【Gitlab】gitrunner并发配置
  • 【Spring】Spring IOCDI:架构旋律中的“依赖交响”与“控制华章”
  • 详细介绍下oracle建库过程中核心脚本dbcore.bsq
  • Linux系统编程之进程控制
  • 华为的USG6000为什么不能ping通
  • 微信小程序 运行出错 弹出提示框(获取token失败,请重试 或者 请求失败)
  • 深入探索HarmonyOS next与ArkTS探索
  • Ubuntu桥接模式设置静态IP
  • 【错误记录】Android Studio 开发环境内存占用过多 ( 记录内存使用情况 )
  • 【系统架构设计师】真题论文: 论无服务器架构及其应用(包括解题思路和素材)
  • 在物理机上安装 Jupyter 的完整指南
  • Spark 内存管理机制
  • androidstudio 最新继承 proto kts 方式
  • WEB开发: 丢掉包袱,拥抱ASP.NET CORE!
  • 代码随想录算法训练营第三十四天 | 62.不同路径 | 63. 不同路径 II | 343.整数拆分 | 96.不同的二叉搜索树
  • 【前端】JavaScript 中的创建对象模式要点
  • java 在方法里,开一个线程,如果报错,不影响原来的方法
  • spring boot有哪些不足之处?
  • NaviveUI框架的使用 ——安装与引入(图标安装与引入)
  • 使用PyPDF2工具加载pdf文件数据
  • Linux C/C++编程之动态库
  • 使用Grafana K6来测测你的系统负载能力