套接字Socket
- Socket编程是基于TCP和UDP协议的。在通信之前,客户端和服务端都要建立一个Socket。
- 在建立Socket时,能够设置的参数是网络层和传输层范围内的。在网络层,Socket函数需要指定是IPv4还是IPv6,还要指定是TCP还是UDP。
- 基于TCP协议的Socket程序函数调用过程:
A.当服务端要监听一个端口之前,一般是先调用bind函数,给这个Socket赋予一个IP地址和端口。(内核要通过TCP头里的端口,来找到相应的应用程序,把包给它。一台机器会有多个网卡,也就会有多个IP地址,网络包需要确定要发送的网卡。)
B.当服务端有了IP地址和端口号,就可以调用listen函数进行监听,进入listen状态,此时客户端就可以发起连接了。(在内核中,为每个Socket维护两个队列:一个是已经建立了连接的队列,此时三次握手已经完毕;一个是还没有完全建立连接的队列,此时三次握手还没完成。)
C.接下来,服务端调用accept函数,对已经完成的连接进行处理。如果连接没有完成,服务端就要等着。
D.在服务端等待时,客户端通过connect函数发起连接。先在参数中指明要连接的IP地址和端口号,然后开始发起三次握手。内核会给客户端分配一个临时的端口,一旦握手成功,服务端的accept就会返回另一个Socket。(监听的Socket和真正用来传数据的Socket不同,一个叫作监听Socket,一个叫作已连接Socket。)
E.连接建立成功之后,双方开始通过read和write函数来读写数据。
- Socket在Linux中是以文件的形式存在的,读写是通过文件描述符进行的。在内核中,每一个进程都有一个数据结构task_struct,里面指向一个文件描述符数组,来列出这个进程打开的文件的文件描述符。文件描述符是一个整数,是这个数组的下标,这个数组中的内容是一个指针,指向内核中打开的文件的列表。既然是一个文件,就会有一个inode,只不过Socket对应的inode不像真正的文件系统一样,保存在硬盘上,而是保存在内存中,在这个inode中,指向了Socket在内核中的Socket结构,在这个结构里,主要是两个队列,一个是发送队列,一个是接收队列,这两个队列里面保存了一些缓存。
- 基于UDP协议的Socket程序函数调用过程:
UDP是没有连接的,所以不需要三次握手,也就不需要调用listen和connect,但是UDP的交互仍然需要IP和端口号,因而也需要bind函数。UDP是没有维护连接状态的,因而不需要每对连接建立一组Socket,而是只要有一个Socket,就能够和多个客户端通信,也正是因为没有连接状态,每次通信时,都可以传入IP地址和端口。
- 能够支撑大量连接的高并发的服务端需要多进程、多线程、epoll机制等。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!