【网络编程】——基于TCP协议实现回显服务器及客户端

个人主页:兜里有颗棉花糖
欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 兜里有颗棉花糖 原创
收录于专栏【网络编程】【Java系列】
本专栏旨在分享学习网络编程的一点学习心得,欢迎大家在评论区交流讨论💌

目录

  • 一、TCP实现回显服务器
  • 二、服务器端
  • 三、客户端
  • 四、运行结果

一、TCP实现回显服务器

TCP提供的API主要有两个类Socket既会给服务器使用也会给客户端使用)和ServerSocket(一般为服务器使用)。TCP将数据分割成以字节为单位的小数据块进行传输(一个TCP数据报就是一个字节数组byte[])。

二、服务器端

在服务器端创建一个ServerSocket对象,并绑定一个端口号。
在这里插入图片描述

进入while循环:
注意这里和Udp实现回显服务器不同的是,Tcp进入循环之后并不是读取客户端请求,而是先处理客户端的连接(Tcp是一个有连接的协议(Udp是没有连接的协议),所以有连接的话会优先处理连接,连接可以理解为客户端和服务器彼此之间保留对方的信息)。一个服务器要应对很多客户端,在服务器内核中有很多客户端的连接,在应用程序层面我们需要对这些连接进行一一处理,这里服务器内核中的连接就像一个一个的待办事项一样,这些待办事项在队列这样的数据结构中,所以应用程序需要一一完成这样的任务(这个过程类似于生产者消费者模型)。
serverSocket.accept()方法可以将服务器内核中的连接获取到应用程序中
在这里插入图片描述

当程序启动之后就会立刻执行到accept方法,在调用serverSocket.accept()方法之后,如果此时没有客户端连接请求到达,该方法会一直阻塞,直到有客户端与服务器成功建立连接才会继续执行。
现在来解释这里的返回值问题,serverSocket.accept()方法会返回一个Socket对象:我们已经直到accept方法会把服务器内核已经建立好的连接拿到应用程序中,但是accpet方法的返回值并非是一个Connection这样的对象,而是Socket这样的对象
这里返回的Socket对象相当于一个耳麦,既可以发出自己的声音也可以听到对方的声音(我们不需要管对方是谁,我们只需要对着这个耳麦说话就行)。然后我们通过Socket对象与对方进行网络通信

SocketServerSocket
ServerSocket类用于在服务器端创建一个服务器套接字,它监听指定的端口,等待客户端的连接请求:通过调用ServerSocket的accept()方法,服务器监听指定端口,直到有客户端发起连接请求,accept()方法才返回一个表示客户端连接的Socket对象。通过这个Socket对象,可以进行与客户端的通信。
Socket类用于创建一个客户端套接字,它是客户端与服务器进行通信的终点:通过调用Socket的构造方法,指定服务器的主机名和端口号,可以与服务器建立连接。
总的来说:ServerSocket用于监听端口,接受客户端的连接请求并返回一个Socket对象,而Socket用于与服务器建立连接,并进行数据的读写操作。通过这两个类的配合,实现了TCP协议下的客户端与服务器之间的通信。

服务器端代码如下

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class TcpEchoServer {private ServerSocket serverSocket = null;private ExecutorService service = Executors.newCachedThreadPool();// 绑定端口号public  TcpEchoServer(int port) throws IOException {serverSocket = new ServerSocket(port);}// 启动服务器public void start() throws IOException {System.out.println("服务器启动!!!");while(true) {// 注意这里和Udp不同的是,Tcp进入循环之后并不是读取客户端请求,而是先处理客户端的连接// Tcp是一个有连接的协议(Udp是没有连接的协议),所以有连接的话会优先处理连接// 连接可以理解为客户端和服务器彼此之间保留对方的信息// 一个服务器要应对很多客户端,在服务器内核中有很多客户端的连接,在应用程序层面我们需要对这些连接进行一一处理// 这里服务器内核中的连接就像一个一个的待办事项一样,这些待办事项在队列这样的数据结构中// 所以应用程序需要一一完成这样的任务Socket clientSocket = serverSocket.accept();
//            Thread t = new Thread(() -> {
//                processConnection(clientSocket);
//            });
//            t.start();service.submit(new Runnable() {@Overridepublic void run() {processConnection(clientSocket);}});}}// 通过这个方法来处理连接的逻辑private void processConnection(Socket clientSocket) {System.out.printf("[%s:%d] 客户端上线啦!!!\n",clientSocket.getInetAddress().toString(),clientSocket.getPort());// 接下来读取请求,根据请求计算响应,最后再返回响应// Socket对象内部包含了两个字节流对象,我们需要先获取到这个字节流对象,然后再完成后续的读写操作try (InputStream inputStream = clientSocket.getInputStream();OutputStream outputStream = clientSocket.getOutputStream()) {// 一次连接中可以涉及到多次请求和响应while( true ) {// 第一步:读取请求并进行解析// 这里为了读取方便,我们直接使用ScannerScanner scanner = new Scanner(inputStream);if(!scanner.hasNext()) {// 读取完毕客户端下线System.out.printf("[%s:%d] 客户端下线!!!\n]",clientSocket.getInetAddress().toString(),clientSocket.getPort());break;}// 这里我们约定客户端输入来的请求是文本数据,同时以空白符作为分割String request = scanner.next();// 第二步:根据请求计算响应String response = process(request);// 第三步:把响应写回给客户端,把OutputStream使用PrinterWriter进行包装,方法进行数据的传输PrintWriter writer = new PrintWriter(outputStream);writer.println(response);// 刷新缓冲区writer.flush();// 打印当前的请求详情System.out.printf("[%s:%d] req: %s, resp: %s\n",clientSocket.getInetAddress().toString(),clientSocket.getPort(),request,response);}} catch (IOException e) {e.printStackTrace();} finally {try {clientSocket.close();} catch (IOException e) {// 这里必须确保Socket能够被关闭e.printStackTrace();}}}private String process(String request) {return request;}public static void main(String[] args) throws IOException {TcpEchoServer server = new TcpEchoServer(9090);server.start();}
}

三、客户端

关于回显服务器这里我们来看客户端的代码是如何进行编写的,主要有4个步骤,如下:

  • 第一步:从控制台上读取用户的输入。
  • 第二部:把输入的内容构造成请求,并将其发送给服务器。
  • 第三步:从服务器读取响应
  • 最后一步:把响应显示到控制台上。

客户端代码如下:

import java.io.*;
import java.net.Socket;
import java.util.Scanner;public class TcpEchoClient {private Socket socket = null;// 要和服务器进行通信的话我们就需要先知道服务器的位置外哪里。public TcpEchoClient(String serverIp,int serverPort) throws IOException {socket = new Socket(serverIp,serverPort);}public void start() {System.out.println("客户端启动!!!");Scanner scannerConsole = new Scanner(System.in);try(InputStream inputStream = socket.getInputStream();OutputStream outputStream = socket.getOutputStream()) {while(true) {// 从控制台输入一个字符串System.out.print("-> ");String request = scannerConsole.next();// 把请求发送给服务器PrintWriter printWriter = new PrintWriter(outputStream);// 使用println加上换行,后续服务器读取请求的时候就可以使用scanner.next来获取了printWriter.println(request);// 调用flush确保数据发送出去了printWriter.flush();// 从服务器中读取响应Scanner scannerNetwort = new Scanner(inputStream);String response = scannerNetwort.next();// 把响应打印出来System.out.println(response);}} catch (IOException e) {e.printStackTrace();}}public static void main(String[] args) throws IOException {TcpEchoClient client = new TcpEchoClient("127.0.0.1",9090);client.start();}
}

四、运行结果

运行结果如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

本文到这里就结束了,希望友友们可以支持一下一键三连哈。嗯,就到这里吧,再见啦!!!
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MacOS M1/M2 Go Debug 配置

前言 换电脑,Go 环境带来一些麻烦,耽误很多时间,稍作记录。 原始电脑是 Mac 旧款,CPU x86 构型,新电脑 M2,因为旧电脑里本地文件很多,为了简化搬迁,还是用了 Mac 自带的迁移&#x…

【单片机项目实战】温度控制系统

本项目的主要作用是实现温度调控,通过设定一个预定的温度值,实现实时检测外界温度,当外界温度小于预定值时,电机正转,实现降温效果;当外界温度大于预定值时,电机反转,实现升温效果&a…

【Android】如何设置应用程序启动Activity(应用启动时显示的界面)

前言 在Android中&#xff0c;AndroidManifest.xml文件可以通过修改来设置应用启动时显示的界面&#xff0c;即启动Activity。 操作步骤 打开AndroidManifest.xml文件。 在文件中找到想要设置为启动Activity的<activity>元素。该元素通常在<application>元素内部…

【数据结构—二叉树的链式结构实现】

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言 一、二叉树的存储结构 二、二叉树链式结构的实现 2.1手动构建一课树 2.2二叉树的遍历 三、二叉树链式结构的实现 3.1前序遍历(递归) 3.2中序遍历(递归) 3.3后序…

人机交互主板定制_基于MT8735安卓核心板的自助查询机方案

人机交互主板是一种商显智能终端主板&#xff0c;广泛应用于广告机、工控一体机、教学一体机、智能自助终端、考勤机、智能零售终端、O2O智能设备、取号机、计算机视觉、医疗健康设备、机器人设备等领域。 人机交互主板采用联发科MTK8735芯片平台&#xff0c;四核Cortex-A53架构…

CTF之Misc杂项干货

目录 一、常见编码 二、文件分析与处理 三、隐写工具与命令 四、隐写术实例 一、常见编码 1、base家族 2、进制转换 3、摩斯、希尔、凯撒、仿射、栏栅、维吉尼亚、培根、键盘、rabbit、rot13、AES、md5、RSA等 &#xff08;md5、RSA可能不会出现在杂项里&#xff0c;但…

OpenHarmony从入门到放弃(三)

OpenHarmony最新的已经使用Ets进行开发了&#xff0c;但是我在使用过程中需要兼容更低的版本&#xff0c;而且大部分的第三方库还是不能使用&#xff0c;所以接下来我还是使用Java进行开发。 一、跳转页面 首先对首页的文字绑定事件&#xff1b; Text myText findComponent…

大数据可视化Web框架——飞致云Dataease在Windows端的安装指南(多图说明版)V2.2最新版

DataEase开源代码在Windows系统开发环境搭建与调试指南_怎么部署dataease 2.0-CSDN博客https://blog.csdn.net/tllhc01/article/details/135220598?spm1001.2014.3001.5502参考这一篇&#xff0c;基于dataease2.2源码进行构建 需要先下载三个文件&#xff0c;且版本一一对应均…

USB 转 TTL线直接读取DS18B20

简介 使用USB转TTL线直接读取DS18B20 温度。 电路图 绘制图 实物图 软件 Download 1-Wire/iButton Drivers for Windows 操作 所有的线路连接好之后将 USB 转 TTL线接到PC上; 安装软件 Download 1-Wire/iButton Drivers for Windows 并打开 软件打开之后先选择串口后 …

【四】CocosCreator-修改引擎源码

看源码的过程中&#xff0c;少不了得修修改改源码&#xff0c;做点实验。果断去找找源码在哪里&#xff0c;然后就可以快乐动手改源码了。 CocosCreator引擎源码主要就是js和原生C两类&#xff0c;分别在引擎目录的resources/engine和resources/cocos2d-x下&#xff0c;如图&am…

【LMM 009】MiniGPT-4:使用 Vicuna 增强视觉语言理解能力的多模态大模型

论文描述&#xff1a;MiniGPT-4: Enhancing Vision-Language Understanding with Advanced Large Language Models 论文作者&#xff1a;Deyao Zhu∗ Jun Chen∗ Xiaoqian Shen Xiang Li Mohamed Elhoseiny 作者单位&#xff1a;King Abdullah University of Science and Techn…

使用Kafka与Spark Streaming进行流数据集成

在当今的大数据时代&#xff0c;实时数据处理和分析已经变得至关重要。为了实现实时数据集成和分析&#xff0c;组合使用Apache Kafka和Apache Spark Streaming是一种常见的做法。本文将深入探讨如何使用Kafka与Spark Streaming进行流数据集成&#xff0c;以及如何构建强大的实…