JavaTCP通信(双项通信、一对一通信、一对多)

目录

双项通信:

 优化1:

优化2:

一对多: 

 总结:一对一通信,一对多通信都是TCP通信的实现,都是双项通信,只有在两机之间连接之前,才有服务端和客户端的区分,而在连接之后就不在有服务端和客户端了,双方都可以互相发送消息


首先需要声明:部分图片来自百战尚学堂

客户端(Socket)和服务端(ServerSocket)连接的前提是主机之间已经通过TCP协议进行了三次握手,客户端和服务端建立连接的基础是主机之间已经通过TCP协议通信的基础之上的

而服务端和客户端在连接之后就没有主客之分了

单项通信我们上一篇文章已经讲过了,今天我们来讲讲双项通信:

单项通信就是客户端固定位发送端,服务端固定为接收端。而双项通信是没有固定的发送端和接收端,双方都可以互相通信,此时我们通过代码讲解一下:

双项通信:

首先我们需要创建服务端ServerSocket对象,因为如果先创建客户端那客户端跟谁连接呢?然后服务端传递参数监听8888端口,然后通过accept方法获取监听器对象,此时这个方法会导致线程阻塞,直到监听器对象连接到客户端才会返回就绪状态

服务端需等待客户端发送的信息,然后服务端才能向客户端发送信息

然后我们创建客户端Socket对象,通过构造方法并传递服务器的IP地址,以及端口号8888,我们需要先向服务端发送信息,才能接收服务端发送的信息

 此时我们就可以通过运行服务端和客户端实现双项通信

 优化1:

但是我们的代码还是不够完善,因为客户端和服务端接收消息都是在同一个线程里的,那么就肯定会涉及到先后的问题而且只能读一句,那么我们在聊天的时候不可能只跟别人说一句话吧,此时我们就需要对代码进行更改,将发送信息和接收消息变为两个线程,让他们并发运行

 首先我们现在服务端实现一个发送消息的线程关于代码如何写的,我的注释都有解释,大家请耐心观看一下

 然后我们创建接收消息的线程,代码的实现逻辑注释都有解释 

然后就是我们的主线程了,此时我们可以看到我们将对应客户端的Socket对象从try的小括号里移了出来因为这个主线程在运行完之后就会死亡,那么try-with-resource这种语法就会将小括号里可以关的都关闭,如果对应客户端的Socket对象关闭了,那么发送消息的线程和接收消息的线程通过什么获取输入输出流呢?所以对应客户端的Socket对象不能在主线程死亡的时候关闭

 而服务端此时的代码就优化完毕了,现在我们来写客户端的发送和接收线程,其实客户端的线程是和服务端一样的所以我们就直接复制了

而客户端的主线程也是一样,客户端Socket对象不能在主线程死亡的时候关闭,所以我们这里就不能使用try-with-resource语法,就用普通的try{...}catch(){...}

验证点对点通信

优化2:

 但是我们可以发现好像这个点对点通信的代码还可以优化,我们看昂,这个服务端和客户端在连接过后就没有主客之分了,而服务端和客户端都有一串相同的代码,那就是发送消息的线程和接收消息的线程,那我们能不能将服务端和客户端写到同一个类中呢?

显然是可以的此时我们创建一个新的类来优化服务端和客户端 

首先我们在主类中创建输入,当输入为server,<port>的时候创建服务端,当输入为<IP>,<port>的时候创建客户端,然后将输入通过split()方法拆分,通过if判断split拆分的数组的第一个元素是否为server,当我们创建好服务端/客户端对象后,创建发送消息and接收消息的线程

 发送消息的线程还是和刚刚写的一样:

 接收消息的线程也一样

此时我们可以通过两次运行此类来创建服务端和客户端,如果不能运行两次同样的类的,找到上边栏的这个按钮

 然后点击这个进行配置

然后点击这个

选择允许多实例

 然后就可以运行两次相同类了 ,然后我们就可以无限制的发送消息和接收消息了,因为这是两个线程并发运行的,互不干扰

一对多: 

那么学到了这里大家应该已经会了点对点的通信了,那么我们可以实现一下一对多的通信,一对多的通信其实很简单嘛,就是将服务端的监听方法accept()方法循环一下不就可以实现监听器一直循环端口了吗,那此时不就形成了一对多的通信了吗

如果没有理解我们通过代码来实现看看:

我们就还是通过之前的代码更改一下,改的地方不多就在监听端口的时候给了个死循环让服务端一直监听某个端口监听到数据过后返回服务端所对应的Socket对象并且每个对应的服务端Socket对象都创建接收消息和发送消息的线程并启动

而服务端没啥区别,就是把下面创建线程的代码放到了else里边,其实放外边也没所谓,一样的效果

 此时我们运行此类,一个服务端,两个客户端

 总结:一对一通信,一对多通信都是TCP通信的实现,都是双项通信,只有在两机之间连接之前,才有服务端和客户端的区分,而在连接之后就不在有服务端和客户端了,双方都可以互相发送消息

 明天我们来写通过TCP实现聊天室

  • 3
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【资源说明】 基于java实现Socket套接字一对一聊天系统源码+项目说明.zip 该项目是个人毕设项目源码,评审分达到95分,都经过严格调试,确保可以运行!放心下载使用。 该项目资源主要针对计算机、自动化等相关专业的学生或从业者下载使用,也可作为期末课程设计、课程大作业、毕业设计等。 具有较高的学习借鉴价值!基础能力强的可以在此基础上修改调整,以实现类似其他功能。 简介 Socket,又称套接字,在TCP/IP协议分层架构中,属应用层和传输层之间的一个抽象层(也有的说是属于传输层),它把TCP/IP层复杂的操作抽象为几个简单的接口供应用层调用以实现进程在网络通信。 ![在这里插入图片描述](README.assets/01.png) ## 1.2 优点 1. 传输数据时间短,性能高 2. 可以加密,数据安全性强 3. 适合客户端和服务器端之间信息实时交互 4. 传输数据为字节级,传输数据可自定义,数据量小 ## 1.3 缺点 相对于http协议传输,增加了开发量 服务端 1. **创建Socket,bind()绑定地址,listen()监听套接字** > ServerSocket只需要一行代码就可以完成创建、绑定、监听Socket,绑定的地址没填默认就是本机的ip(在源码中InetAddress.anyLocalAddress()方法得出的结论),监听Socket监听的是改Socket的最大连接数,如果队列满时,会出现提示,并拒绝连接(源码的listen(int backlog)方法这样解释)。 ```java ServerSocket serverSocket = new ServerSocket(端口号); ``` 2. **accept()监听连接** > accept()方法侦听要与ServerSocket建立的连接并接受它。该方法会阻塞,直到建立连接。 ``` Socket socket = serverSocket.accept(); ``` 3. **read()读数据** 客户端 1. **创建Socket、connect()连接Socket** 客户端创建Socket,`new Socket(String host, int port);`需要抛出异常,当IP地址错误、端口号错误、服务器`ServerSocket`未启动时,都会抛出异常,即连接失败。 ```java try { Socket socket = new Socket(String host, int port); } catch (Exception e) { e.printStackTrace(); } ``` 2. **write()写数据** > 同服务端 3. **read()读数据** > 同服务端 4. **close()关闭连接** ```java // 方法一: socket.close(); // 方法二: // 给服务器发送相关消息,由服务器断开与指定客户端的连接 【备注】更多详情介绍见项目说明!
好的,我可以为您提供一些关于使用Java编写与ESP8266进行TCP通信的应用程序的指导。 首先,您需要使用Java中的Socket类来创建TCP连接。在与ESP8266通信之前,您需要确定ESP8266的IP地址和端口号。这些信息通常在ESP8266的文档中可以找到。 接下来,您需要使用Java网络编程功能来打开套接字连接并发送数据。您可以使用Java的InputStream和OutputStream来接收和发送数据。使用Java中的BufferedReader和PrintWriter可以更方便地读取和写入数据。 下面是一个简单的Java代码示例,演示如何连接到ESP8266,并发送和接收数据: ``` import java.net.*; import java.io.*; public class ESP8266Communication { public static void main(String [] args) { String serverName = "ESP8266 IP address"; int port = 1234; try { System.out.println("Connecting to " + serverName + " on port " + port); Socket client = new Socket(serverName, port); System.out.println("Connected to " + client.getRemoteSocketAddress()); OutputStream outToServer = client.getOutputStream(); PrintWriter out = new PrintWriter(outToServer); out.println("Hello from Java!"); out.flush(); InputStream inFromServer = client.getInputStream(); BufferedReader in = new BufferedReader(new InputStreamReader(inFromServer)); System.out.println("Server says: " + in.readLine()); client.close(); } catch (IOException e) { e.printStackTrace(); } } } ``` 请记住,您需要将代码中的"ESP8266 IP address"和"port"替换为您ESP8266的实际IP地址和端口号。同时,ESP8266也需要使用类似的代码来接收和发送数据。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值