Keyboard shortcuts

Press or to navigate between chapters

Press ? to show this help

Press Esc to hide this help

套接字

复习

  • 端口:标识主机上的通信端点
  • NAT:用地址与端口的映射共享公网地址
  • TCP / UDP:两种不同的传输方式

TL;DR

  • 套接字是应用程序收发网络数据的接口
  • 它由传输协议、IP 与端口共同标识
  • 应用通过一系列系统调用创建、连接和收发数据
  • 套接字把网络细节封装起来,只留下简单的读写

正文

  前面讲的都是协议内部的机制。可对写程序的人来说,怎么真正用上网络呢?

  答案是套接字(socket)——可以把它理解成应用程序伸向网络的那个“插口”。

一个插口,几个要素

  一个套接字,通常由这几样东西共同确定:

  • 用哪种传输协议(TCP 还是 UDP)
  • 本地的 IP 地址与端口
  • 远端的 IP 地址与端口

  这正好把我们前面学的东西串了起来:IP 定位主机,端口定位程序,协议决定可靠与否。应用只管对着这个插口读写,剩下的都由操作系统和协议去操心。

一次典型的通信流程

  以 TCP 为例,服务端和客户端的动作大致是:

  • 服务端:创建套接字 → 绑定端口 → 监听 → 接受连接
  • 客户端:创建套接字 → 发起连接 → 连接成功
  • 双方:发送、接收数据
  • 结束:关闭套接字

  这些动作,本质上都是在调用操作系统提供的系统调用。还记得操作系统那一部分讲的“用户程序通过系统调用请求内核服务”吗?收发网络数据,正是其中最重要的一类服务。

封装得恰到好处

  套接字最妙的地方,是它把一大堆复杂细节藏了起来:

  • 三次握手、序号确认、超时重传
  • 滑动窗口、流量控制、拥塞控制
  • 数据包的封装与解析

  应用开发者完全不必操心这些,只需要像读写文件一样,对着套接字读读写写即可。这又是“加一层”的胜利:把复杂性留在下面,把简单留给用户。

  从下一章开始,我们就站到应用层,看看最常见的几种网络服务——DNS、HTTP——是怎样使用这套接口的。

思考题 1

  套接字为什么可以看成“传输协议 + IP + 端口”的组合?

思考题 2

  套接字把哪些网络细节封装了起来,让应用不必关心?

小结

知识点

  • 套接字是应用访问网络的接口
  • 由协议、本地与远端 IP 和端口确定
  • 通过系统调用完成创建、连接与收发
  • 它封装了传输层的复杂机制

参考资料

  1. Wikipedia(zh):Berkeley套接字:应用访问网络的编程接口
  2. Wikipedia(zh):系统调用:用户程序请求内核服务的方式

思考题答案(仅供参考)

思考题 1

  因为要唯一确定一条通信,需要知道“用哪种方式传”(协议)、“我是谁”(本地 IP 与端口)、“对方是谁”(远端 IP 与端口)。这些要素合在一起,正好确定一个套接字,对应一条具体的通信。

思考题 2

  它封装了三次握手、序号与确认、超时重传、滑动窗口、流量控制、拥塞控制,以及数据包的封装与解析等细节。应用只需调用接口收发数据,像读写文件一样,无需关心底层协议如何处理。

协议

  本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。

封面图

设计师 | 南国微雪