Java 简单实现一个 TCP 回显服务器

文章目录

  • TCP 服务端
  • TCP 客户端
  • 实现效果
  • TCP 服务端(实现字典功能)
  • 总结


TCP 服务端

package network;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.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class TcpEchoServer {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) {Socket clientSocket = serverSocket.accept();service.submit(new Runnable() {@Overridepublic void run() {processConnection(clientSocket);}});/*            Thread thread = new Thread(() -> {processConnection(clientSocket);});thread.start();*/}}// 通过这个方法来处理一个连接的逻辑.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) {// 1. 获取请求并解析, 使用 Scanner 来读取Scanner scanner = new Scanner(inputStream);if (!scanner.hasNext()) {// 读取完毕, 客户端下线!System.out.printf("[%s:%d] 客户端下线!\n", clientSocket.getInetAddress().toString(), clientSocket.getPort());break;}// 这个代码暗含一个约定, 客户端发过来的请求, 得是文本数据, 同时, 还得带有空白符作为分割. (比如换行这种)String request = scanner.next();// 2. 根据请求计算响应结果String response = process(request);// 3. 把响应结果写回客户端//    把 OutputStream 使用 PrinterWriter 包裹一下, 方便进行发数据.PrintWriter writer = new PrintWriter(outputStream);//    使用 PrintWriter 的 println 方法, 把响应返回给客户端.//    此处用 println, 而不是 print 就是为了在结尾加上 \n . 方便客户端读取响应, 使用 scanner.next 读取.writer.println(response);//    这里还需要加一个 "刷新缓冲区" 操作.writer.flush();// 4. 日志显示当前请求详情.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) {e.printStackTrace();}}}public String process(String request) {return request;}public static void main(String[] args) throws IOException {TcpEchoServer server = new TcpEchoServer(9090);server.start();}
}

TCP 客户端

package network;import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
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) {// 1. 在控制台上输入字符串.System.out.print("-> ");String request = scannerConsole.next();// 2. 将请求发送给服务器.PrintWriter writer = new PrintWriter(outputStream);writer.println(request);writer.flush();// 3. 从服务器读取响应.Scanner scannerNetwork = new Scanner(inputStream);String response = scannerNetwork.next();// 4. 显示响应.System.out.println(response);}} catch (IOException e) {e.printStackTrace();}}public static void main(String[] args) throws IOException {TcpEchoClient client = new TcpEchoClient("localHost", 9090);client.start();}
}

实现效果

在这里插入图片描述
在这里插入图片描述

TCP 服务端(实现字典功能)

只需要继承自之前写的服务端, 然后重写父类 process 方法即可. 添加一些查询字典的逻辑.

package network;import java.io.IOException;
import java.util.HashMap;public class TcpDictServer extends TcpEchoServer {private HashMap<String, String> dict = new HashMap<>();public TcpDictServer(int port) throws IOException {super(port);dict.put("dog", "小狗");dict.put("cat", "小猫");dict.put("hello", "你好");}@Overridepublic String process(String request) {return dict.getOrDefault(request, "查询的单词不存在!");}public static void main(String[] args) throws IOException {TcpDictServer server = new TcpDictServer(9090);server.start();}
}

效果

在这里插入图片描述

在这里插入图片描述


总结

✨ 本文记录了一个简单的 TCP 回显服务器代码.
✨ 想了解更多计算机网络的知识, 可以收藏一下本人的计算机网络学习专栏, 里面会持续更新本人的学习记录, 跟随我一起不断学习.
✨ 感谢你们的耐心阅读, 博主本人也是一名学生, 也还有需要很多学习的东西. 写这篇文章是以本人所学内容为基础, 日后也会不断更新自己的学习记录, 我们一起努力进步, 变得优秀, 小小菜鸟, 也能有大大梦想, 关注我, 一起学习.

再次感谢你们的阅读, 你们的鼓励是我创作的最大动力!!!!!

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

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

相关文章

从0到0.01入门React | 010.精选 React 面试题

🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云课上架的前后端实战课程《Vue.js 和 Egg.js 开发企业级健康管理项目》、《带你从入…

【入门Flink】- 10基于时间的双流联合(join)

统计固定时间内两条流数据的匹配情况&#xff0c;需要自定义来实现——可以用窗口&#xff08;window&#xff09;来表示。为了更方便地实现基于时间的合流操作&#xff0c;Flink 的 DataStrema API 提供了内置的 join 算子。 窗口联结&#xff08;Window Join&#xff09; 一…

vmware workstation 与 device/credential guard 不兼容

VM虚拟机报错 vmware虚拟机启动时报错&#xff1a;vmware workstation 与 device/credential guard 不兼容&#xff1a; 系统是win10专业版&#xff0c;导致报错原因最终发现是安装了docker&#xff0c;docker自带下载虚拟机Hyper-V&#xff0c;而导致vmware workstation 与 …

git分支与tag标签的介绍与使用)

git分支与tag标签的介绍与使用 一.什么是分支与标签1.2.开发环境分层 二git分支介绍2.1分支操作2.2.IDEA中操作分支 三、Git标签的讲解3.1.GitBashHere操作标签3.2. IDEA中操作标签 一.什么是分支与标签 分支&#xff08;Branches&#xff09;&#xff1a; 功能开发&#xff…

Ubuntu取消sudo的输入密码

Ubuntu最近要安装软件&#xff0c;每次sudo都要输入一次密码&#xff0c;感觉很麻烦&#xff0c;于是想能不能设置为不输入密码&#xff0c;在网上找了一下解决办法。 主要参考这篇文章&#xff1a; Ubuntu取消sudo时输入密码 上面这篇文章使用的是vim&#xff0c;但是按照博…

github私有仓库开发,公开仓库发布版本

文章目录 github私有仓库开发,公开仓库发布版本需求背景实现思路GitHub Releases具体步骤广告 github私有仓库开发,公开仓库发布版本 需求背景 github私有仓库开发,公开仓库发布版本&#xff0c;既可以保护源代码,又可以发布版本给用户使用。许多知名软件项目都采用了这样的开…

mysql主从复制-使用心得

文章目录 前言环境配置主库从库 STATEMENTbinloggtidlog-errorDistSQL总结 前言 mysql 主从复制使用感受&#xff0c;遇到一些问题的整理&#xff0c;也总结了一些排查问题技巧。 环境 mysql5.7 配置 附&#xff1a;千万级数据快速插入配置可以参考&#xff1a;mysql千万数…

【Liunx】服务器解决 跨域问题

首先打开后端的站点 在站点设置内打开 "配置文件" 然后在 “server_name 本机ip ”下方添加跨域配置,添加成功后重启nginx即可 add_header Access-Control-Allow-Origin *; add_header Access-Control-Allow-Methods GET, POST, OPTIONS, PUT, DELETE; add_header A…

业务出海之服务器探秘

这几年随着国内互联网市场的逐渐饱和&#xff0c;越来越多的公司加入到出海的行列&#xff0c;很多领域都取得了很不错的成就。虽然出海可以获得更加广阔的市场&#xff0c;但也需要面对很多之前在国内可能没有重视的一些问题。集中在海外服务器的选择维度上就有很大的变化。例…

数据分析实战 | 泊松回归——航班数据分析

目录 一、数据及分析对象 二、目的及分析任务 三、方法及工具 四、数据读入 五、数据理解 六、数据准备 七、模型训练 八、模型评价 一、数据及分析对象 CSV文件&#xff1a;o-ring-erosion-only.csv 数据集链接&#xff1a;https://download.csdn.net/download/m0_7…

从0到0.01入门React | 001.精选 React 面试题

🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云课上架的前后端实战课程《Vue.js 和 Egg.js 开发企业级健康管理项目》、《带你从入…