Socket套接字

Socket套接字
FlawSocket概览:
什么是 Socket?
Socket(套接字)是网络通信中的一种机制,可以将其类比为电话插座,负责连接通信双方。Socket 就像电话插座上的孔,端口负责连接,而创建连接就像把插头插在插座上。Socket 实例创建后会监听消息,当有消息传入时会自动接通。
实际上,Socket 是应用层和传输层之间的抽象层,它将 TCP/IP 层复杂的操作封装成简单接口,供应用层调用,从而实现进程间的网络通信。Socket 起源于 UNIX,在 UNIX 的“一切皆文件”思想下,进程间通信通过文件描述符(file descriptor)进行,Socket 就是这种“打开-读/写-关闭”模式的实现。服务器和客户端各自维护一个“文件”,通过文件读写来传输数据,通讯结束时关闭文件。
Socket 的位置
Socket 位于应用层和传输层之间。它将复杂的网络协议封装成简洁的接口,便于程序进行网络通信。
Socket 的类型
Socket 主要分为两种类型:流格式套接字(SOCK_STREAM)和数据报格式套接字(SOCK_DGRAM)。
流格式套接字(SOCK_STREAM)
流格式套接字也叫“面向连接的套接字”,是一种可靠、双向的通信数据流,可以确保数据准确无误地到达另一台计算机。如果数据损坏或丢失,可以重新发送。
特点:
- 数据不会在传输过程中丢失。
- 数据按照顺序传输。
- 数据发送和接收不同步。
可以将 SOCK_STREAM 比作一条传送带,数据按顺序传输,不会丢失。数据传输时,无需接收端和发送端同步,接收端可以根据自己的节奏读取数据。
应用场景:
- 浏览器使用的 HTTP 协议:基于面向连接的套接字,确保数据准确无误。
流格式套接字使用 TCP 协议(Transmission Control Protocol,传输控制协议),TCP 确保数据按照顺序到达且无错误。
数据报格式套接字(SOCK_DGRAM)
数据报格式套接字也叫“无连接的套接字”,它传输数据时不进行数据校验。如果数据在传输中损坏或丢失,无法补救。这种套接字传输效率高,但数据传输顺序不保证,可能丢失或损坏。
特点:
- 强调快速传输而非传输顺序。
- 数据可能丢失或损毁。
- 每次传输的数据大小有限。
- 数据的发送和接收同步。
可以将 SOCK_DGRAM 比作快递,一些包裹可能丢失或损坏,但传输效率高。
应用场景:
- QQ 视频聊天和语音聊天:使用 SOCK_DGRAM 来传输数据,保证通信效率,即使丢失少量数据,也不会影响整体通信质量。
数据报格式套接字使用 UDP 协议(User Datagram Protocol,用户数据报协议),它注重快速传输,而非可靠性。
Socket 通信过程
Socket 保证了不同计算机之间的通信,也就是网络通信。对于网站,通信模型是服务器与客户端之间的通信。两端都建立了一个 Socket 对象,然后通过 Socket 对象对数据进行传输。通常服务器处于一个无限循环,等待客户端的连接。
下面是面向连接的 TCP 时序图:
客户端过程
客户端的通信过程较为简单,创建 Socket 后连接服务器,然后发送数据、接收响应数据,最后关闭连接。
1 | import socket |
sendall() 方法会尝试发送所有数据,成功时返回 None,失败时抛出异常。recv() 方法用于接收服务器返回的数据。
服务端过程
服务端先初始化 Socket,与本机地址及端口绑定,准备接收连接。调用 accept() 阻塞等待客户端连接,连接建立后,接收并处理请求,发送响应数据,最后关闭连接。
1 | import socket |
accept() 方法阻塞等待客户端连接,返回新的 Socket 对象 conn,通过 conn 与客户端通信。
从 TCP 连接的视角看 Socket 过程
TCP 三次握手的 Socket 过程
- 服务器初始化 Socket,调用
socket()、bind()、listen(),调用accept()阻塞等待。 - 客户端调用
connect()向服务器发送 SYN 请求。 - 服务器发送 SYN 和 ACK 应答,完成第一次握手。
- 客户端收到应答后返回,再发送一个 ACK。
- 服务器接收 ACK 确认,
accept()返回,建立连接。
TCP 四次挥手的 Socket 过程
- 某个应用进程调用
close()主动关闭,发送一个 FIN。 - 另一端接收到 FIN 后被动关闭,发送 ACK。
- 被动关闭的一端调用
close()关闭 Socket,发送 FIN。 - 接收端发送 ACK 确认,连接关闭。
注意: 服务端代码在实际应用中需要并发处理,服务器通常会 fork 新的进程或线程来处理请求,以提高处理能力。
Socket 是网络通信的基础,通过理解 Socket,可以更好地进行网络编程和应用开发。希望这篇文章能帮助你理解 Socket 的概念及其应用场景。如果有疑问,欢迎在评论区讨论!













