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通信相关的理解,希望能帮到大家,有问题的地方欢迎大家一起讨论!

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/927957.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

java基础概念46-数据结构1

一、引入 List集合的三种实现类使用了不同的数据结构! 二、数据结构的定义 三、常见的数据结构 3-1、栈 特点:先进后出,后进先出。 java内存容器: 3-2、队列 特点:先进先出、后进后出。 栈VS队列-小结 3-3、数组 3-…

python: Treeview Pagination

# encoding: utf-8 # 版權所有 2024 ©塗聚文有限公司 # 許可資訊查看:言語成了邀功的功臣,還需要行爲每日來值班嗎? # 描述: Treeview Pagination # Author : geovindu,Geovin Du 塗聚文. # IDE : PyCharm 2023.1…

C# winform非常好用的图表开源控件Scottplot

wifnorm自带的chart控件功能和性能都不太行,所以在网上搜索到了Scottplot开源图表控件。根据自己需要,将已经试验使用过的用法记录在这里 winform建议使用版本 Scottplot包版本:4.1.71 这个版本在winform中可以以控件形式直接拖拉到窗体中使…

SQL面试50题

数据表关系图 数据表 CREATE TABLE student (id int(11) NOT NULL AUTO_INCREMENT,name varchar(255) NOT NULL,sex enum(female,male) NOT NULL,birth date NOT NULL,credit float(5,2) DEFAULT NULL,PRIMARY KEY (id) ) ENGINEInnoDB AUTO_INCREMENT25 DEFAULT CHARSETutf8;…

Redis(配置文件属性解析)

一、tcp-backlog深度解析 tcp-backlog是一个TCP连接的队列,主要用于解决高并发场景下客户端慢连接问题。配置文件中的“511”就是队列的长度,对联与TCP的三次握手有关,不同的linux内核,backlog队列中存放的元素(客户端…

Vue3 脚手架扩展

当 yarn dev 运行成功后,我们继续添加扩展 首先我们要安装一些依赖 其中的vue-router和vuex安装最新版的就行,因为项目是vue3 element-plus和less,less-loader最好按照我这个版本来下载 element-plus是一个vue常用的ui组件库 element-plus/…

TCP/IP协议簇自学笔记

摘抄于大学期间记录在QQ空间的一篇自学笔记,当前清理空间,本来想直接删除掉的,但是感觉有些舍不得,因此先搬移过来。 曾经,我只知道socket函数能进行网络间数据的通信,知道tcp/ip协议也是用来进行网络数据…

AI开发:逻辑回归 - 实战演练- 垃圾邮件的识别(二)

接上一篇AI开发:逻辑回归 - 实战演练- 垃圾邮件的识别(一) new_email 无论为什么文本,识别结果几乎都是垃圾邮件,因此我们需要对源码的逻辑进行梳理一下: 在代码中,new_email 无论赋值为何内容都被识别为…

字符串处理(二)

第1题 篮球比赛 查看测评数据信息 学校举行篮球比赛,请设计一个计分系统统计KIN、WIN两队分数,并输出分数和结果! 如果平分就输出‘GOOD’,否则输出获胜队名! 输入格式 输入数据共n1行, 第1行n&#xf…

【数据库系列】Liquibase 与 Flyway 的详细对比

在现代软件开发中,数据库版本控制是一个至关重要的环节。为了解决数据库迁移和变更管理的问题,开发者们通常会使用工具,如 Liquibase 和 Flyway。本文将对这两个流行的数据库迁移工具进行详细比较,从基础概念、原理、优缺点到使用…

企业品牌曝光的新策略:短视频矩阵系统

企业品牌曝光的新策略:短视频矩阵系统 在当今数字化时代,短视频已经渗透到我们的日常生活之中,成为连接品牌与消费者的关键渠道。然而,随着平台于7月20日全面下线了短视频矩阵的官方接口,许多依赖于此接口的小公司和内…

PostgreSQL最常用数据类型-重点说明自增主键处理

简介 PostgreSQL提供了非常丰富的数据类型,我们平常使用最多的基本就3类: 数字类型字符类型时间类型 这篇文章重点介绍这3中类型,因为对于高并发项目还是推荐:尽量使用简单类型,把运算和逻辑放在应用中,…

做异端中的异端 -- Emacs裸奔之路4: 你不需要IDE

确切地说,你不需要在IDE里面编写或者阅读代码。 IDE用于Render资源文件比较合适,但处理文本,并不划算。 这的文本文件,包括源代码,配置文件,文档等非二进制文件。 先说说IDE带的便利: 函数或者变量的自动…

ospf协议(动态路由协议)

ospf基本概念 定义 OSPF 是典型的链路状态路由协议,是目前业内使用非常广泛的 IGP 协议之一。 目前针对 IPv4 协议使用的是 OSPF Version 2 ( RFC2328 );针对 IPv6 协议使用 OSPF Version 3 ( RFC2740 )。…

【热门主题】000072 分布式数据库:开启数据管理新纪元

前言:哈喽,大家好,今天给大家分享一篇文章!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏关注哦 💕 目录 【热…

Python 3 教程第33篇(MySQL - mysql-connector 驱动)

Python MySQL - mysql-connector 驱动 MySQL 是最流行的关系型数据库管理系统,如果你不熟悉 MySQL,可以阅读我们的 MySQL 教程。 本章节我们为大家介绍使用 mysql-connector 来连接使用 MySQL, mysql-connector 是 MySQL 官方提供的驱动器。…

ENSP IPV6-over-IPV4

IPv6是网络层协议的第二代标准协议,一个IPv6地址同样可以分为网络前缀和主机ID两个部分。 可以将IPV4的网络看成IPV6的承载网,只有IPv4网络是连通的,则IPv6网络才有可能连通。所以配置的时候需要先配置IPv4网络的路由功能,再配IP…

《数据挖掘:概念、模型、方法与算法(第三版)》

嘿,数据挖掘的小伙伴们!今天我要给你们介绍一本超级实用的书——《数据挖掘:概念、模型、方法与算法》第三版。这本书是数据挖掘领域的经典之作,由该领域的知名专家编写,系统性地介绍了在高维数据空间中分析和提取大量…

53 基于单片机的8路抢答器加记分

目录 一、主要功能 二、硬件资源 三、程序编程 四、实现现象 一、主要功能 首先有三个按键 分别为开始 暂停 复位,然后八个选手按键,开机显示四条杠,然后按一号选手按键,数码管显示30,这…

从零开始写游戏之斗地主-网络通信

在确定了数据结构后,原本是打算直接开始写斗地主的游戏运行逻辑的。但是突然想到我本地写出来之后,也测试不了啊,所以还是先写通信模块了。 基本框架 在Java语言中搞网络通信,那么就得请出Netty这个老演员了。 主要分为两个端&…