Socket 通信机制详解

Socket 是网络编程中一种重要的通信机制,它允许不同的计算机通过网络进行数据交换。

一、 Socket 的概念

Socket(套接字)是计算机网络编程中的一种抽象,它提供了在网络上进行通信的接口。

Socket 本质上是一种通信的端点,它在网络上标识了一个通信链路的两端,并提供了通信双方所需的接口和功能。

通过使用 Socket,可以在不同计算机之间建立连接,并进行数据的传输和交换(网络通信)

二、 Socket 类型

在 Socket 编程中,常见的两种类型是 TCP Socket 和 UDP Socket。

  • TCP Socket:TCP(传输控制协议)是一种面向连接的协议,它提供可靠的、有序的数据传输。TCP Socket 基于 TCP 协议,使用三次握手建立连接,确保数据的可靠性和顺序性。

  • UDP Socket:UDP(用户数据报协议)是一种无连接的协议,它提供了简单的数据传输服务,但不保证数据的可靠性和顺序性。UDP Socket 基于 UDP 协议,无需建立连接,适用于一些实时性要求高、允许一定数据丢失的应用场景。

三、 Socket 的工作原理

3.1 三次握手

这里需要先讲一下TCP 协议中的三次握手。

同步序号:SYN   确认字段:ACK  随机数据:seq

规定:

当SYN=1,ACK=0表示连接请求

当SYN=1,ACK=1表示同意建立连接

如上图,纵向的轴,是一个时间轴。

第一次握手:时间点1,客户端向服务端发送连接请求报文段。ACK=0,SYN=1,seq=x

将SYN位置为1,Sequence Number为x;然后,客户端进入SYN_SEND状态,等待服务器的确认;

第二次握手:服务器收到SYN报文段。服务器收到客户端的SYN报文段,需要对这个SYN报文段进行确认,设置Acknowledgment Number为x+1(Sequence Number+1);同时,自己自己还要发送SYN请求信息,将SYN位置为1,Sequence Number为y;服务器端将上述所有信息放到一个报文段(即SYN+ACK报文段)中,一并发送给客户端,此时服务器进入SYN_RECV状态;

第三次握手:客户端收到服务器的SYN+ACK报文段。然后将Acknowledgment Number设置为y+1,向服务器发送ACK报文段,这个报文段发送完毕以后,客户端和服务器端都进入ESTABLISHED状态,完成TCP三次握手。

完成了三次握手,客户端和服务器端就可以开始传送数据。


TCP/IP 三次握手:

TCP/IP 三次握手_tcp三次握手-CSDN博客

创建 Socket与TCP/IP 三次握手有什么关系:

在 TCP 协议中,建立连接通常需要进行三次握手,而创建 Socket 对象通常是在握手之前的准备工作之一用于准备建立连接所需的资源和信息。(创建一个套接字,收集一些计算机的资源,将一些资源绑定套接字里面,以及接受和发送数据的函数等等,这些功能接口在一起构成了socket的编程。)

具体来说,在客户端发起连接之前,通常会创建一个 Socket 对象,然后调用 connect 方法来发起连接请求;

而在服务器端接受连接之前,通常会创建一个 Socket 对象,然后调用 accept 方法来接受连接请求并返回一个新的 Socket 对象,用于与客户端进行通信。

3.2  Socket 的工作原理

当客户端和服务端使用 Socket 进行通信时,它们的工作原理有所不同。

3.2.1 客户端的 Socket 工作原理

  1. 创建 Socket 对象:客户端首先会创建一个 Socket 对象,用于与服务器端建立连接。

  2. 连接服务器:客户端通过调用 Socket 对象的 connect 方法来连接服务器。在连接过程中,客户端会发送连接请求给服务器端。

  3. 发送数据:一旦连接建立成功,客户端就可以通过 Socket 对象的 send 方法向服务器端发送数据。发送的数据通常包括请求信息、参数等。

  4. 接收数据:客户端通过 Socket 对象的 recv 方法来接收服务器端发送的响应数据。客户端会等待服务器端的响应,并在接收到响应后进行相应的处理。

  5. 关闭连接:通信结束后,客户端会调用 Socket 对象的 close 方法来关闭连接,并释放资源。

3.2.2 服务端的 Socket 工作原理

  1. 创建 Socket 对象:服务器端首先会创建一个 Socket 对象,用于监听客户端的连接请求。

  2. 绑定地址和端口:服务器端会将 Socket 对象绑定到一个特定的地址和端口上,以便客户端能够连接到该地址和端口。

  3. 监听连接:服务器端通过调用 Socket 对象的 listen 方法来开始监听客户端的连接请求。一旦调用了 listen 方法,服务器就处于等待客户端连接的状态。

  4. 接受连接:当客户端发起连接请求时,服务器端会调用 accept 方法来接受连接。在接受连接之后,服务器端会创建一个新的 Socket 对象,用于与该客户端进行通信。

  5. 接收和处理数据:一旦连接建立成功,服务器端就可以通过新创建的 Socket 对象来接收客户端发送的数据,并进行相应的处理。服务器端会等待客户端发送数据,并在接收到数据后进行解析和处理。

  6. 发送数据:服务器端也可以通过 Socket 对象的 send 方法向客户端发送数据。这通常发生在服务器端需要向客户端发送响应或其他信息时。

  7. 关闭连接:通信结束后,服务器端会调用 Socket 对象的 close 方法来关闭连接,并释放资源。

总的来说,客户端和服务端的 Socket 工作原理都涉及创建 Socket 对象、建立连接、发送和接收数据以及关闭连接等步骤,但具体的操作和流程略有不同。客户端主要负责发起连接和发送请求,而服务端主要负责监听连接、接受连接和处理请求。

四、代码

4.1 Java代码

4.1.1 客户端代码WebClient

import java.io.*;
import java.net.*;
import java.util.Scanner;public class WebClient {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);String messageA; // 储存A发送的消息try {// 创建 Socket,连接到服务器的 IP 地址和端口Socket socket = new Socket("127.0.0.1", 8888);// 获取输入流和输出流InputStream inputStream = socket.getInputStream();OutputStream outputStream = socket.getOutputStream();while (true) {  // 一直保持发送System.out.print("输入消息:" + '\t');// 输入消息messageA = scanner.nextLine();// 发送消息给服务器outputStream.write(messageA.getBytes());outputStream.flush(); // 刷新缓冲区,确保消息发送给服务器// 接收服务器的响应byte[] buffer = new byte[1024];int length = inputStream.read(buffer);String response = new String(buffer, 0, length);System.out.println("B: " + response);}// 关闭连接
//            outputStream.close();
//            inputStream.close();
//            socket.close();} catch (IOException e) {System.out.println(e.getMessage());}}
}

4.1.2 客户端代码WebServer

import java.io.*;
import java.net.*;
import java.util.Scanner;public class WebServer {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);String messageB = ""; // 储存B发送的消息try {// 创建 ServerSocket,监听指定的端口ServerSocket serverSocket = new ServerSocket(8888);System.out.println("服务启动,等待客户端连接... ");// 等待客户端连接Socket socket = serverSocket.accept();// 获取输入流和输出流InputStream inputStream = socket.getInputStream();OutputStream outputStream = socket.getOutputStream();while (true) {// 接收客户端发送的数据byte[] buffer = new byte[1024];int length = inputStream.read(buffer);String message = new String(buffer, 0, length);System.out.println("A: " + message);System.out.print("输入消息:" + '\t');messageB = scanner.nextLine();// 发送响应给客户端outputStream.write(messageB.getBytes());outputStream.flush(); // 刷新缓冲区,确保消息发送给客户端}// 关闭连接
//            outputStream.close();
//            inputStream.close();
//            socket.close();
//            serverSocket.close();} catch (IOException e) {e.printStackTrace();}}
}

运行结果:

这样我们就实现了基于 TCP 协议的长连接。

TCP(传输控制协议)是一种可靠的、面向连接的协议,它提供了数据传输的可靠性和顺序性。在 TCP 长连接中,客户端和服务器之间建立一次连接后,可以持续地在该连接上进行数据传输,直到其中一方显式地关闭连接为止。TCP 长连接适合于需要保持持续通信的场景,例如即时通讯、远程控制等。

既然tcp协议的长连接就能实现续通信的场景,为什么还要用web Socket 呢?

尽管 TCP 协议的长连接可以实现持续通信的场景,但 WebSocket 协议在某些情况下更适合。

  1. 更轻量级的通信开销: WebSocket 协议相比于 HTTP 协议(即基于长连接的 HTTP 长轮询或者服务器推送技术)具有更轻量级的通信开销。WebSocket 在建立连接后,在客户端和服务器之间建立了全双工的通信通道,通过一个简单的握手过程后,数据可以在客户端和服务器之间进行双向实时通信,无需每次都携带 HTTP 的头部信息,减少了通信的开销。

  2. 更低的延迟: WebSocket 协议通过在客户端和服务器之间建立长期的双向通信通道,可以实现实时的双向通信,从而降低了通信的延迟。对于需要实时性较高的应用场景,如在线游戏、实时聊天等,WebSocket 可以提供更好的用户体验。

  3. 更方便的API: WebSocket 提供了更简洁、方便的 API,使得开发者可以更容易地实现实时通信功能。客户端和服务器端都可以使用相同的编程模型来处理 WebSocket 连接,简化了开发流程。

  4. 更好的跨域支持: WebSocket 协议在跨域通信方面具有更好的支持,因为 WebSocket 握手过程中的 HTTP 头部信息可以包含跨域资源共享(CORS)的相关信息,使得跨域通信更加方便。

4.2 pyhton代码

4.2.1 服务端代码

# -*- coding:utf-8 -*-
# @Author: 喵酱
# @time: 2024 - 04 -10
# @File: server.py
# desc:
import socketdef main():# 创建套接字server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)# 绑定IP地址和端口server_socket.bind(('localhost', 8888))# 监听连接server_socket.listen(1)print("服务启动,等待客户端连接... ")# 接受客户端连接client_socket, client_address = server_socket.accept()print(f"客户端 {client_address} 已连接")while True:try:# 接收客户端消息message = client_socket.recv(1024).decode()print("A:", message)# 发送消息给客户端message_b = input("输入消息:")client_socket.send(message_b.encode())except Exception as e:print("发生异常:", e)break# 关闭连接client_socket.close()server_socket.close()if __name__ == "__main__":main()

4.2.2 客户端代码

# -*- coding:utf-8 -*-
# @Author: 喵酱
# @time: 2024 - 04 -10
# @File: client.py
# desc:
import socketdef main():# 创建套接字client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)# 连接服务器client_socket.connect(('localhost', 8888))while True:try:# 发送消息给服务器message_a = input("输入消息:")client_socket.send(message_a.encode())# 接收服务器响应response = client_socket.recv(1024).decode()print("B:", response)except Exception as e:print("发生异常:", e)break# 关闭连接client_socket.close()if __name__ == "__main__":main()

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

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

相关文章

C++ ─── 类和对象(上)

目录 1.面向过程和面向对象初步认识 2.类的引入 3.类的定义 3.1 类的成员函数两种定义方式: 4.类的访问限定符及封装 4.1 访问限定符 4.2 封装 5.类的作用域 6.类的实例化 7.类对象模型 7.1 如何计算类对象的大小 7.2 结构体内存对齐规则 8.this指针 …

CSS display属性

目录 概述: 设置display示例: none: block: inline: inline-block : 概述: 在CSS中我们可以使用display属性来控制元素的布局,我们可以通过display来设置元素的类型。 在不设置…

IO-序列化流

简介 这个流是为了传输对象而生的对象序列化:把java对象写入到文件中对象反序列化:把文件中的对象读出来 继承体系 ObjectInputStream:把文件中的对象读出来ObjectOutputStream:把java对象写入到文件中 常用API 示例 实体类必须实现序列化接口这其实就是…

【Excel2LaTeX】复杂表格制作的解决方案

刚开始用LaTeX写论文,遇到的第一道坎就是绘制表格,较小的普通表格可以通过简单的语法实现,但是较大的复杂的表格却让我无从下手。 Excel2LaTeX插件 这里介绍一种我用到非常顺手的工具:Excel2LaTeX插件,下载地址&#x…

C语言 【函数】

1.函数概述 函数是一种可重用的代码块&#xff0c;用于执行特定任务或完成特定功能 函数作用&#xff1a;对具备相同逻辑的代码进行封装&#xff0c;提高代码的编写效率&#xff0c;实现对代码的重用 2. 函数的使用 2.1 无参无返回值 #include <stdio.h>// 函数名…

AWS Key disabler:AWS IAM用户访问密钥安全保护工具

关于AWS Key disabler AWS Key disabler是一款功能强大的AWS IAM用户访问密钥安全保护工具&#xff0c;该工具可以通过设置一个时间定量来禁用AWS IAM用户访问密钥&#xff0c;以此来降低旧访问密钥所带来的安全风险。 工具运行流程 AWS Key disabler本质上是一个Lambda函数&…

Methoxy PEG Propionic acid具有良好的亲水性和分子量可控性

【试剂详情】 英文名称 mPEG-PA&#xff0c;mPEG-Propionic acid&#xff0c; Methoxy PEG PA&#xff0c; Methoxy PEG Propionic acid 中文名称 聚乙二醇单甲醚丙酸&#xff0c; 甲氧基-聚乙二醇-丙酸 外观性状 由分子量决定&#xff0c;固体或者液体 分子量 400&…

在Postgres中,如何有效地管理大型数据库的大小和增长

文章目录 一、定期清理和维护1. VACUUM和ANALYZE2. 删除旧数据和归档 二、分区表三、压缩数据四、配置优化1. 调整维护工作负载2. 监控和日志 五、使用外部存储和扩展1. 外部表和FDW2. 扩展和插件 六、定期备份和恢复测试结论 管理大型数据库的大小和增长是数据库管理员&#x…

粒子群算法及基于该算法的典型问题求解实践

说明 我在上个月(3.15&#xff0c;时间过得真快&#xff0c;已经一个月了…)写了两篇关于遗传算法的博文[1]&#xff1a;遗传算法及基于该算法的典型问题的求解实践-CSDN博客 和[2]&#xff1a;基于遗传算法的波束形成优化-仿真实践-CSDN博客&#xff0c;当时关注到该算法时&am…

Vuforia AR篇(一)— 开启AR之门

目录 前言一、 Vuforia Engine简介二、主要功能与特点2.1 图像识别2.2 VuMarks技术2.3 多目标识别2.4 圆柱体目标识别2.5 平面跟踪技术2.6 云服务支持2.7 模型目标识别2.8 区域目标识别 三、平台兼容性四、技术实现结语 前言 随着科技的不断发展&#xff0c;增强现实&#xff…

授权协议OAuth 2.0之如何接入授权服务

写在前面 为了能够更好以场景化的方式来理解OAuth2.0&#xff0c;本文一起看下&#xff0c;假定我们现在要开发一个交友类软件&#xff0c;为了提高用户登录的便利程度&#xff0c;需要对接微信开放平台&#xff0c;获取到用户的微信账号信息&#xff0c;作为用户的注册信息来…

Java面试八股文(JVM篇)(❤❤)

Java面试八股文_JVM篇 1、知识点汇总2、知识点详解&#xff1a;3、说说类加载与卸载11、说说Java对象创建过程12、知道类的生命周期吗&#xff1f;14、如何判断对象可以被回收&#xff1f;17、调优命令有哪些&#xff1f;18、常见调优工具有哪些20、你知道哪些JVM性能调优参数&…

Unity Pro 2019 for Mac:专业级游戏引擎,助力创意无限延伸!

Unity Pro 2019是一款功能强大的游戏开发引擎&#xff0c;其特点主要体现在以下几个方面&#xff1a; 强大的渲染技术&#xff1a;Unity Pro 2019采用了新的渲染技术&#xff0c;包括脚本化渲染流水线&#xff0c;能够轻松自定义渲染管线&#xff0c;通过C#代码和材料材质&…

react v18 项目初始化

按照以下命令进行傻瓜式操作即可&#xff1a; 全局安装脚手架工具&#xff1a; npm install -g create-react-app创建项目my-react-app&#xff1a; create-react-app my-react-app安装 antd: yarn add antd安装 react-router-dom&#xff1a; yarn add react-router-dom启动项…

第十五届蓝桥杯大赛软件赛省赛 C/C++ 大学 B 组(基础题)

试题 C: 好数 时间限制 : 1.0s 内存限制: 256.0MB 本题总分&#xff1a;10 分 【问题描述】 一个整数如果按从低位到高位的顺序&#xff0c;奇数位&#xff08;个位、百位、万位 &#xff09;上 的数字是奇数&#xff0c;偶数位&#xff08;十位、千位、十万位 &…

汽车咨询|基于SprinBoot的汽车资讯管理系统设计与实现(源码+数据库+文档)

汽车资讯管理系统目录 基于SprinBoot的汽车资讯管理系统设计与实现 一、前言 二、系统设计 三、系统功能设计 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&#xff1a; 博主介绍&#xff1a;✌️大厂码农|毕设布道师&#xff…

机器学习基础入门(一)(机器学习定义及分类)

机器学习定义 给予计算机无需特意带有目的性编程便有学习能力的算法 深度学习算法 主要有监督学习和非监督学习两类 监督学习&#xff08;supervised learning&#xff09; 定义 1、学习由x映射到y的映射关系 2、主动给予机器学习算法正确示例&#xff0c;算法通过示例来学习…

意大利侍酒师Galvan Maurizia分享意大利葡萄酒与美食文化魅力

在酒水行业日益繁荣的今天&#xff0c;消费者对酒类产品的品质、文化和品味的追求不断提升。为了满足这一市场需求&#xff0c;云仓酒庄近日宣布开启首届《综合品酒师》培训&#xff0c;旨在培养更多具备专业素养和品鉴能力的品酒师&#xff0c;为酒水行业的专业化和形象提升注…

PTA 编程题(C语言)-- 统计字符

题目标题&#xff1a;统计字符 题目作者&#xff1a;颜晖 浙大城市学院 本题要求编写程序&#xff0c;输入10个字符&#xff0c;统计其中英文字母、空格或回车、数字字符和其他字符的个数。 输入格式: 输入为…

Gradle系列(3)——Gradle extension(gradle扩展),如何自定义gradle扩展,AppPlugin,AppExtension原理

文章目录 1.什么是Extensions2.如何自定义Extension3.问题来了——如何通过自定义Extension给Plugin传递数据4.BaseAppModuleExtension和AppPlugin部分原理BuildTypes是如何创建并传递数据给AppPlugin的&#xff1f;AppPlugin是如何接收数据的&#xff1f;buildTypeContainer流…