TCP的socket API

1、核心类

ServerSocket :服务器使用的socket

Socket : 服务器和客户端都会使用的socket

accept进行的工作是拉客

对应操作系统来说,建立TCP连接是内核的工作

accept要干的就是等连接建立好了,把这个连接给拿到应用程序中。

如果当前连接还没建立,accept就会阻塞,accept相当于,有人给你打电话了,你按下接听键!如果没人打电话,就阻塞等待。

一、回显服务器

 1、服务器

注:

1、代码中,使用了 clientSocket 用完之后,需要关闭。

和代码中 ServerSocket 生命周期不一样,ServerSocket的生命周期跟随整个程序, clientSocket生命周期,只是当前连接。就应该在连接之后,把这里的 socket 关闭,不关就会造成资源泄露。ServerSocket只有一个,clientSocket 会有无数个,每个客户端的连接,都是一个。

2、利用多线程,来实现多个客户端同时运行

一个线程调用一个processConnect。

3、通过线程池,来解决频繁创建销毁线程的问题

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;public TcpEchoServer(int port) throws IOException {serverSocket = new ServerSocket(port);}public void start() throws IOException {System.out.println("服务器启动!");//创建线程池ExecutorService service = Executors.newCachedThreadPool();while (true){Socket clientSocket = serverSocket.accept();//[版本1] 单线程版本,存在bug,无法处理多个客户端//不是直接调用,而是创建一个新的线程,让新的线程来调用。//processConnect(clientSocket);//[版本2] 多线程版本,主线程负责拉客,新线程负责通信//虽然比版本1有提升,但是涉及到频繁创建销毁线程,在高并发的情况下,负担是比较重的
//            Thread T = new Thread(() -> {
//                try {
//                    processConnect(clientSocket);
//                } catch (IOException e) {
//                    e.printStackTrace();
//                }
//            });
//            T.start();//[版本3] 使用线程池,来解决频繁创建销毁线程的问题service.submit(new Runnable() {@Overridepublic void run() {try {processConnect(clientSocket);} catch (IOException e) {e.printStackTrace();}}});}}//通过这个方法,给当前连上的这个客户端,提供服务//一个连接过来了,服务方式可能有两种://1、一个连接只进行一次数据交互(一个请求+一个响应) 短连接//2、一个连接进行多次数据交互(N个请求 + N个响应)  长连接//此处写长连接的版本,短连接就是长连接去掉while循环public void processConnect(Socket clientSocket) throws IOException {System.out.printf("[%s:%d] 建立连接\n",clientSocket.getInetAddress().toString(),clientSocket.getPort());try(InputStream inputStream = clientSocket.getInputStream();OutputStream outputStream = clientSocket.getOutputStream()){Scanner scanner = new Scanner(inputStream);PrintWriter printWriter = new PrintWriter(outputStream);//这里是长连接的写法,需要while来获取多次交互情况while (true){if(!scanner.hasNext()){//读完了,就断开连接。即当客户端断开连接的时候,此时 hasnext 就会返回 false//读到EOF的时候(end of file)返回false,当客户端进程退出的时候,也就会触发socket文件关闭,此时服务器这边尝试读取请求,就会读到EOFSystem.out.printf("[%s:%d] 断开连接\n",clientSocket.getInetAddress().toString(),clientSocket.getPort());break;}//1、读取请求并解析String request = scanner.next();//2、根据请求计算响应String response = process(request);//3、把响应写回给客户端printWriter.println(response);//4、刷新一下缓冲区,避免数据没有真的发出去printWriter.flush();System.out.printf("[%s:%d] req:%s;resp:%s\n",clientSocket.getInetAddress().toString(),clientSocket.getPort(),request,response);}}finally {clientSocket.close();}}public String process(String req){return req;}public static void main(String[] args) throws IOException {TcpEchoServer echoServer = new TcpEchoServer(8000);echoServer.start();}
}

2、客户端

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;public class TcpEchoClient {private Socket socket = null;public TcpEchoClient() throws IOException {//new这个对象的时候,需要和服务器建立连接 建立连接,就得知道,服务器在哪里//new Socket的过程就是建立连接的过程socket = new Socket("127.0.0.1",8000);}public  void start() throws IOException {//由于实现的是长连接,一个连接会处理 N 个请求和响应,需要加上while循环//从键盘输入Scanner scanner = new Scanner(System.in);try(InputStream inputStream = socket.getInputStream();OutputStream outputStream = socket.getOutputStream()) {//从网络上输入Scanner scannerNet = new Scanner(inputStream);PrintWriter printWriter = new PrintWriter(outputStream);while(true){//1、从控制台读取用户输入System.out.print("> ");String request = scanner.next();//2、把请求发送给服务器printWriter.println(request);printWriter.flush();//3、从服务器读取响应String response = scannerNet.next();//4、把结果显示到界面上System.out.printf("req:%s resp:%s\n",request,response);}}}public static void main(String[] args) throws IOException {TcpEchoClient echoClient = new TcpEchoClient();echoClient.start();}
}

二、翻译服务器

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;public class TcpDictServer extends TcpEchoServer{private Map<String,String> dict = new HashMap<>();public TcpDictServer(int port) throws IOException {super(port);dict.put("cat","小猫");dict.put("dog","小狗");dict.put("宝贝","瑾瑾");}@Overridepublic String process(String req){return dict.getOrDefault(req,"俺也不知道");}public static void main(String[] args) throws IOException {TcpDictServer server = new TcpDictServer(8000);server.start();}
}

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

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

相关文章

小米 红米 Redmi note11 4G 5G 手机解锁BL 秒BL解锁 教程 跳过168小时 selenes evergo线刷机包下载

红米&#xff08;Redmi&#xff09;Note 11 5G 手机BL解锁 红米note11 4G/5G 秒解锁BL锁 方法 教程 跳过168小时 新版本 selenes evergo 红米Note11系列版本非常多&#xff0c;从4G开始一直到后面出现的11R&#xff0c;我们常见的机型有红米 Note11/11Pro/11Pro/11SE/11R等等&…

【游戏逆向】探索可靠的线程检查方法

一、关键的线程检查 在对抗外挂和木马的方案中&#xff0c;不可能将所有的检查操作放在主线程中&#xff0c;因此&#xff0c;在方案中总有一个扫描线程或者环境检查线程必须保持工作&#xff0c;而它们也就成了外挂和木马的重要攻击目标&#xff0c;外挂和木马只要搞定了它们…

5.1阻塞和非阻塞、同步和异步 5.2Unix、Linux上的五种IO模型

5.1阻塞和非阻塞、同步和异步 典型的一次IO的两个阶段是什么&#xff1f;数据就绪和数据读写 数据就绪&#xff1a;根据IO操作的就绪状态 阻塞非阻塞 数据读写&#xff1a;根据应用程序和内核的交互方式 同步异步 陈硕&#xff1a;在处理IO的时候&#xff0c;阻塞和非阻塞都…

架构分层方法指导

在《不过时的经典层架构》里讲了经典的四层架构怎样对易变性做封装。咱们实际项目中&#xff0c;如果没有足够的实践和关键性思考&#xff0c;还是很可能使用名义上科学的分类理论&#xff0c;却在按照功能进行架构分层。今天咱们就通过一些简单的指导来尽量减少这种风险。 四问…

PDF转换软件有哪些?分享免费好用的PDF转换工具!

PDF是在办公和学习中常用的文件格式&#xff0c;它包含文字、图片、数据等各种信息&#xff0c;可以说是功能丰富。然而&#xff0c;有时我们需要将PDF转换为PPT格式以便于演示&#xff0c;或者将其转换为Word格式以节省内存空间。这时候就需要使用PDF转换软件。下面我将介绍一…

java投票管理系统小程序

投票管理系统小程序 演示视频 技术&#xff1a; 基于springbootvue小程序的投票管理系统的设计与实现 运行环境&#xff1a; JAVA版本&#xff1a;JDK1.8 IDE类型&#xff1a;IDEA、Eclipse都可运行 微信开发这工具 数据库类型&#xff1a;MySql&#xff08;8.x版本都可&am…

#10048 「一本通 2.2 练习 4」Censoring(内附封面)

[USACO15FEB] Censoring S 题面翻译 Farmer John为他的奶牛们订阅了Good Hooveskeeping杂志&#xff0c;因此他们在谷仓等待挤奶期间&#xff0c;可以有足够的文章可供阅读。不幸的是&#xff0c;最新一期的文章包含一篇关于如何烹制完美牛排的不恰当的文章&#xff0c;FJ不愿…

机器学习6:使用 TensorFlow 的训练线性回归模型

纸上得来终觉浅&#xff0c;绝知此事要躬行。前面 5 篇文章介绍了机器学习相关的部分基础知识&#xff0c;在本章&#xff0c;笔者将讲解基于 TensorFlow 实现一个简单的线性回归模型&#xff0c;以便增强读者对机器学习的体感。 目录 1.环境准备 1.1 安装 Python3 1.2 安装…

尚硅谷微信小程序开发 仿网易云音乐App 小程序 后端接口服务器搭建

小程序学习 尚硅谷微信小程序开发 项目网易云小程序学习地址&#xff1a; 01-尚硅谷-小程序-课程介绍_哔哩哔哩_bilibili 视频相关的教程文档与笔记分享 链接&#xff1a;https://pan.baidu.com/s/1aq7ks8B3fJ1Wahge17YYUw?pwd7oqm 提取码&#xff1a;7oqm 配套服务器 老师…

品牌方的brief怎么写,注意事项

我们都知道&#xff0c;对于产品传播来说&#xff0c;达人起着重要的作用。可又是什么影响着达人的传播结果呢?今天给大家分享下&#xff0c;品牌方的brief怎么写的注意事项。 一、什么是brief 可能有的朋友&#xff0c;还不太清楚&#xff0c;到底什么是brief。Brief&#xf…

用python实现调用百度图片搜索的API

前言&#xff1a;这段代码是一个简单的图片爬虫程序它可以通过输入关键词&#xff0c;在百度图片中搜索相关图片&#xff0c;并返回一张随机的图片。代码使用Flask框架搭建了一个简单的Web应用&#xff0c;将用户输入的关键词作为参数传递给爬虫程序&#xff0c;然后从百度图片…

linux 资源包安装详细教程

linux 资源包安装详细教程 一、离线下载安装1.1 下载1.2 安装1.3 错误&#xff1a;依赖检测失败 - 解决方案1.4 查看安装的包情况 二、在线安装 一、离线下载安装 1.1 下载 点击进入网页&#xff1a;linux资源包下载链接&#xff1a;pkgs.org在搜索栏输入需要的包&#xff0c…