网络编程套接字2

之前我们已经介绍了UDP套接字流程,接下来我们介绍TCP流套接字编程,TCP的一个核心特点,面向字节流,读写数据的基本单位就是字节。

1.API介绍

1.1ServerSocket:是创建TCP服务器Socket的API(专门给服务器用);

方法:

(服务器启动需要先绑定端口号)

TCP是“有连接”,这里的accept是联通连接的关键操作。

2.Socket

Socket是客户端Socket,或服务端中接收到客⼾端建⽴连接(accept⽅法)的请求后,返回的服 务端Socket(服务器和客户端都可以用)。

方法:

这两个参数是服务器的IP和服务器的端口。

代码实例:

TcpEchoServer

public class TcpEchoServer {private ServerSocket serverSocket = null;// 这里和 UDP 服务器类似, 也是在构造对象的时候, 绑定端口号.public TcpEchoServer(int port) throws IOException {serverSocket = new ServerSocket(port);}public void start() throws IOException {System.out.println("启动服务器");// 这种情况一般不会使用 fixedThreadPool, 意味着同时处理的客户端连接数目就固定了.ExecutorService executorService = Executors.newCachedThreadPool();while (true) {// tcp 来说, 需要先处理客户端发来的连接.// 通过读写 clientSocket, 和客户端进行通信.// 如果没有客户端发起连接, 此时 accept 就会阻塞.// 主线程负责进行 accept, 每次 accept 到一个客户端, 就创建一个线程, 由新线程负责处理客户端的请求.Socket clientSocket = serverSocket.accept();// 使用多线程的方式来调整
//            Thread t = new Thread(() -> {
//                processConnection(clientSocket);
//            });
//            t.start();// 使用线程池来调整executorService.submit(() -> {processConnection(clientSocket);});}}// 处理一个客户端的连接.// 可能要涉及到多个客户端的请求和响应.private void processConnection(Socket clientSocket) {System.out.printf("[%s:%d] 客户端上线!\n", clientSocket.getInetAddress(), clientSocket.getPort());try (InputStream inputStream = clientSocket.getInputStream();OutputStream outputStream = clientSocket.getOutputStream()) {// 针对 InputStream 套了一层Scanner scanner = new Scanner(inputStream);// 针对 OutputStream 套了一层PrintWriter writer = new PrintWriter(outputStream);// 分成三个步骤while (true) {// 1. 读取请求并解析. 可以直接 read, 也可以借助 Scanner 来辅助完成.if (!scanner.hasNext()) {// 连接断开了System.out.printf("[%s:%d] 客户端下线!\n", clientSocket.getInetAddress(), clientSocket.getPort());break;}String request = scanner.next();// 2. 根据请求计算响应String response = process(request);// 3. 返回响应到客户端// outputStream.write(response.getBytes());writer.println(response);writer.flush();// 打印日志System.out.printf("[%s:%d] req: %s, resp: %s\n", clientSocket.getInetAddress(), clientSocket.getPort(),request, response);}} catch (IOException e) {throw new RuntimeException(e);} finally {try {clientSocket.close();} catch (IOException e) {throw new RuntimeException(e);}}}private String process(String request) {return request;}public static void main(String[] args) throws IOException {TcpEchoServer server = new TcpEchoServer(9090);server.start();}
}

服务器引⼊多线程, 如果只是单个线程,⽆法同时响应多个客⼾端,此处给每个客⼾端都分配⼀个线程.

// 启动服务器 
public void start() throws IOException {System.out.println("服务器启动!");while (true) {Socket clientSocket = serverSocket.accept();Thread t = new Thread(() -> {processConnection(clientSocket);});t.start();}
}

 服务器引⼊线程池 为了避免频繁创建销毁线程,也可以引⼊线程池.

// 启动服务器 
public void start() throws IOException {System.out.println("服务器启动!");ExecutorService service = Executors.newCachedThreadPool();while (true) {Socket clientSocket = serverSocket.accept();// 使⽤线程池, 来解决上述问题 service.submit(new Runnable() {@Overridepublic void run() {processConnection(clientSocket);}});}
}

TCPEchoClient

public class TcpEchoClient {private Socket socket = null;public TcpEchoClient(String serverIp, int serverPort) throws IOException {// 直接把字符串的 IP 地址, 设置进来.// 127.0.0.1 这种字符串socket = new Socket(serverIp, serverPort);}public void start() {Scanner scanner = new Scanner(System.in);try (InputStream inputStream = socket.getInputStream();OutputStream outputStream = socket.getOutputStream()) {// 为了使用方便, 套壳操作Scanner scannerNet = new Scanner(inputStream);PrintWriter writer = new PrintWriter(outputStream);// 从控制台读取请求, 发送给服务器.while (true) {// 1. 从控制台读取用户输入String request = scanner.next();// 2. 发送给服务器writer.println(request);//    加上刷新缓冲区操作, 才是真正发送数据writer.flush();// 3. 读取服务器返回的响应.String response = scannerNet.next();// 4. 打印到控制台System.out.println(response);}} catch (IOException e) {throw new RuntimeException(e);}}public static void main(String[] args) throws IOException {TcpEchoClient client = new TcpEchoClient("127.0.0.1", 9090);client.start();}
}

1. 创建socket对象就会在底层和对端建立TCP连接,及记录了对端的信息(服务器的IP和端口),不需要自己在创建变量保存了,直接TCP内部就保存了。

 2.

这两个socket对象不是同一个对象(它们在不同的进程中,甚至在不同的主机上)。

3.行为是自动加上\n

这个操作只是把数据放到“发送缓冲区”中,还没有真正写入到网卡中;如果这里使用print,则数据发过去,服务器收到了,但没有真正处理。

暗含一个约定,一个请求/响应,使用\n作为结束标记,对端读的时候,也是读到\n就结束(认为读到一个完整的请求)。

4.flush方法来“冲刷缓冲区”,才算真正的发送数据。

5.

判断收到的数据中是否包含“空白符”,遇到空白符(比如换行、回车、空格、制表符、翻页符...),认为一个“完整的next”,遇到之前都会堵塞。

6.

在这里clientSocket的生命周期是伴随一次连接的,每个客户端连接,都会创建一个新的;每个客户端断开连接,这个对象也就可以不要了,这时就需要加一个close(),防止文件的泄露。

TCP发送数据时,需要先建⽴连接,什么时候关闭连接就决定是短连接还是⻓连接:

  • 短连接:每次接收到数据并返回响应后,都关闭连接,即是短连接。也就是说,短连接只能⼀次收发 数据。
  • ⻓连接:不关闭连接,⼀直保持连接状态,双⽅不停的收发数据,即是⻓连接。也就是说,⻓连接可 以多次收发数据。

对⽐以上⻓短连接,两者区别如下:

  •  建⽴连接、关闭连接的耗时:短连接每次请求、响应都需要建⽴连接,关闭连接;⽽⻓连接只需要 第⼀次建⽴连接,之后的请求、响应都可以直接传输。相对来说建⽴连接,关闭连接也是要耗时 的,⻓连接效率更⾼。
  •  主动发送请求不同:短连接⼀般是客⼾端主动向服务端发送请求;⽽⻓连接可以是客⼾端主动发送 请求,也可以是服务端主动发。
  • 两者的使⽤场景有不同:短连接适⽤于客⼾端请求频率不⾼的场景,如浏览⽹⻚等。⻓连接适⽤于 客⼾端与服务端通信频繁的场景,如聊天室,实时游戏等。

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

偌依-防重复提交

其中的使用工具类可去偌依的代码中查找 需要配合 springboot自定义过滤器构建可重复读取inputStream的request(来源若依) springboot自定义过滤器构建可重复读取inputStream的request(来源若依)-CSDN博客 定义注解 package co…

3D 数组插值 MATLAB

插值是一种根据现有数据点创建的趋势查找查询数据点值的方法。MATLAB 提供了许多选项来对 N 维数据执行插值。 在本文中,我们将讨论如何借助一些示例在 3D 数组中插入数据。我们将使用 MATLAB 的 interpn() 函数来执行插值。 语法 vq interp…

如何在Typora中绘制流程图

如何在Typora中绘制流程图 在撰写文档时,清晰的流程图能极大地提升信息传递的效率。Typora是一款优秀的Markdown编辑器,支持通过Mermaid语法快速绘制流程图。本文将介绍如何在Typora中创建和自定义流程图,帮助你用更直观的方式呈现逻辑结构和…

SpringBoot集成Redis(全流程详解)

前言 通过在SpringBoot中集成Redis,详细梳理集成过程。包括SpringBoot启动过程中,容器的刷新、自动配置的流程、各类注解的处理。 类比在纯Spring中集成Redis,体验SpringBoot自动配置给开发带来了哪些便利。 一、测试样例 1.1配置文件 a…

机器人控制技术、传感器技术、Wi-Fi无线通信技术、AI视觉应用教学和实训: 智能小车车臂教学平台

1、基本介绍 智能车臂教学平台在硬件上采用模块化设计,主控板、运动车体、机械臂、各类传感器等都可以进行拆卸操作;在接口上,采用标准拔插式设计,减少接线,方便组装。使用Wi-Fi与控制软件进行通信,支持遥…

ssm113ssm框架的购物网站+vue(论文+源码)_kaic

毕 业 设 计(论 文) 题目:网上超市系统设计与实现 摘 要 现代经济快节奏发展以及不断完善升级的信息化技术,让传统数据信息的管理升级为软件存储,归纳,集中处理数据信息的管理方式。本网上超市系统就是在这…

C++ 里面散发的咖喱味儿 - Currying函数式编程

C 里面散发的咖喱味儿 - Currying函数式编程 大家好,最近几篇都在聊C里面的函数式编程,今天我们继续就某一个点来深入聊一下,来聊聊在 C 中如何使用 std::bind 来实现函数式编程,尤其是柯里化(Currying)这…

【Gitee版】一篇教你如何快速入门git(详解)

前言--区分Git与Gitee Git 是一个强大的分布式版本控制系统,用于管理源代码。市面上有很多基于git的仓库网站,例如:GitHub、Gitee、GitCode等,它们之间的关系就好像是:git为基类,剩余为子类的样子。使用的…

Linux系统编程学习 NO.11——进程的概念(2)

谈谈进程的性质 进程的竞争性 由于CPU资源是稀缺的,进程数量是众多的。不可避免需要造成进程排队等待CPU资源的动作,内核的设计者为了让操作系统合理的去调度这这些进程,就产生了进程优先级的概念。设置合理的进程优先级能让不同进程公平的去竞争CPU资…

灵神 刷题DAY1

Python与java的刷题的区别 1. Python没有分号 2. Python不能return的时候赋值 3. Python没有小括号和花括号 4. Python的循环很奇怪&#xff0c;没有for(int i0;i<32;i)这种形式 而是直接用的是for i in range(n)这种 5. Python中没有 6. Python中没有&& 是an…

Nginx中使用keepalive实现保持上游长连接实现提高吞吐量示例与测试

场景 HTTP1 .1之后协议支持持久连接&#xff0c;也就是长连接&#xff0c;优点在于在一个TCP连接上可以传送多个HTTP请求和响应&#xff0c; 减少了建立和关闭连接的消耗和延迟。 如果我们使用了nginx去作为反向代理或者负载均衡&#xff0c;从客户端过来的长连接请求就会被…

【Spring AOP 原理】

首先AOP跟OOP(面向对象编程)、IOC(控制反转)一样都是一种编程思想 跟OOP不同, AOP是面向切面编程, 面对多个不具备继承关系的对象同时需要引入一段公共逻辑的时候, OOP就显得有点笨重了, 而AOP就游刃有余, 一个切面可以横跨多个类或者对象去执行公共逻辑, 极大的提升了开发效率…

Vue3集成搜索引擎智能提示API

需求&#xff1a; 如何在项目中实现像百度搜索框一样的智能提示效果&#xff0c;如下图所示&#xff1a; 相关知识&#xff1a; 下面是各厂商提供的免费API 厂商请求百度http://suggestion.baidu.com/su?wd中国&cbwindow.baidu.sug必应http://api.bing.com/qsonhs.as…

python3的基本数据类型:可变集合的用法

一. 简介 前面学习了 python3中的一种基本数据类型-集合&#xff0c;文章如下&#xff1a; python3的基本数据类型&#xff1a;集合的创建与分类-CSDN博客 本文继续学习 Python3中的集合&#xff0c;主要学习 可变集合的用法。 二. python3的基本类型&#xff1a;可变集合的…

从零开始:我的鸿蒙学习之旅(二)

前言 记录我在学习鸿蒙操作系统过程中的成长&#xff0c;旨在激励我自己&#xff0c;也希望能激发读者们的学习热情&#xff0c;一起愉快地探索鸿蒙开发的世界&#xff01; 我说说这几天的学习成果吧&#xff0c;将开发入门的第一部分的剩下小节以及第二部分的第一小结写完了…

SSM学习记录(一)之SSM整合

SSM学习记录&#xff08;一&#xff09;之SSM整合 一、SSM整合二、SSM整合的核心问题1、SSM需要几个IoC容器2、每个IoC容器对应哪些类型组件3、IoC容器之间的关系和调用方向4、具体有多少配置以及对应的容器的关系5、IoC初始化方式和配置位置 一、SSM整合 微观&#xff1a;将学…

【从理论到应用】HTTP请求响应详解 (请求数据格式,请求方式,Web开发中的体现)

目录 一.HTTP协议 二.HTTP请求数据格式 请求方式 三.Web开发中的HTTP请求与响应 接收HTTP请求 同一响应格式 四.使用第三方工具发送HTTP请求&#xff08;Apifox、postman、Yapi&#xff09; 一.HTTP协议 HTTP&#xff08;Hypertext Transfer Protocol&#xff0c;超…

猎板PCB罗杰斯板材的应用案例

以下是几个猎板 PCB 与罗杰斯板材结合的具体案例&#xff1a; 案例一&#xff1a;5G 通信基站天线 PCB 在 5G 通信基站的天线系统中&#xff0c;对高频信号的传输和处理要求极高。猎板 PCB 采用罗杰斯板材&#xff0c;凭借其稳定的低介电常数&#xff08;如 RO4003C 板材&…

基于Java Springboot快递物流管理系统

一、作品包含 源码数据库全套环境和工具资源部署教程 二、项目技术 前端技术&#xff1a;Html、Css、Js、Layui 数据库&#xff1a;MySQL 后端技术&#xff1a;Java、Spring Boot、MyBatis 三、运行环境 开发工具&#xff1a;IDEA 数据库&#xff1a;MySQL8.0 数据库管…