Socket

Socket是计算机网络的一个抽象概念,它封装了计算机网络通信的一组api/方法实现,如send(), recev(), connect().

Socket分为Stream Sockets( TCP ), Datagram Sockets( UDP ) 两种类型.

Kernel Implementation of Socket

  1. Data Structure
    • Type and Status
      记录 socket 的类型(如流、数据报)、协议(如 TCP、UDP)和当前的状态(如连接中、已连接、监听中).
    • Manipulate function pointers
      这是一个函数指针表,根据 socket 的类型和协议,指向相应的内核函数,如数据发送、接收、连接建立等.
    • Protocol Control Block (PCB)
      这是管理 TCP 或 UDP 连接状态的核心数据结构。对于 TCP,这通常是 TCP 控制块 (TCB),包含了诸如序列号、窗口大小、连接队列等信息.
  2. Life Cycle
    • Create
      当应用程序调用如 socket() 的系统调用时,内核会初始化一个 socket 数据结构。根据指定的地址族和协议类型,分配并初始化协议控制块
    • Bind
      通过 bind() 系统调用,将本地地址(IP 地址和端口号)分配给 socket。内核更新 socket 数据结构中的相关字段,并在网络接口中注册这个地址
    • Listen
      对于 TCP 服务器来说,listen() 调用标志着 socket 准备接受连接。内核配置 socket 为监听状态,并准备接受队列来管理来自客户端的连接请求
    • Connect
      TCP 的 connect() 调用触发三次握手过程,建立客户端和服务器之间的连接。UDP 不需要建立连接,但也可以通过 connect() 指定默认的远程地址
    • Send/Receive
      数据发送和接收通过 send()recv() 系统调用处理。内核利用缓冲区管理数据,保证数据按序传输和接收
    • Close
      close() 系统调用负责断开连接并释放 socket 资源。对于 TCP,这通常涉及发送 FIN 包,执行四次挥手过程来关闭连接

Address Family

地址族是指定网络地址类型的一种方式,主要用来定义地址和协议的范围,用于指定Socket的网络类型
主要的地址族
1. IPv4 (AF_INET)
这是最常用的地址族,用于IPv4网络通信。IPv4地址由四组数字组成,每组一字节(例如,192.168.1.1)。
2. IPv6 (AF_INET6)
随着IPv4地址的耗尽,IPv6成为必要,提供了更大的地址空间。IPv6地址使用128位地址空间,比IPv4的32位长得多(例如,2001:0db8:85a3:0000:0000:8a2e:0370:7334)。
3. Unix域(本地)(AF_UNIXAF_LOCAL)
用于同一台机器上运行的进程间通信,不通过网络层。Unix域套接字使用文件系统路径作为地址。
4. 无地址族 (AF_UNSPEC)
这个地址族用于套接字操作中不指定具体地址族的情况,通常用在特定的配置或初始化中。
例如,以这种方式指定地址族:

#include <sys/socket.h>
int sockfd = socket(AF_INET, SOCK_STREAM, 0);

Websocket

Websocket是一种在TCP连接上进行全双工(Full Duplex)通信的方法。在完成TCP握手并建立http连接后,连接会保持开放,允许数据在客户端和服务器之间双向流动,直到任一方主动关闭连接。

Why?

在Http协议的设计之初,主要用途是查看文本页面,并未考虑如在线游戏,直播的应用场景,因此它在全双工的Http协议上采用了半双工的实现。Http如果想长时间与服务器保持连接,只能采用长轮询(Long polling)的方法,主要流程如下:

  1. 客户端向服务器发送请求
  2. 服务器保持连接,直到其发送消息
  3. 当消息出现时,服务器使用该消息响应请求
  4. 浏览器再次发出新请求

From: https://www.wallarm.com/what/a-simple-explanation-of-what-a-websocket-is

因此需要一种在TCP上实现全双工的协议,即Websocket.

Websocket与Socket几乎没有关系.

How?

  1. 握手:首先,客户端通过发送一个 HTTP 请求到服务器来初始化一个 WebSocket 连接。这个 HTTP 请求使用 Upgrade 头从 HTTP 协议切换到 WebSocket 协议(协议升级).
    GET ws://websocketexample.com:8181/ HTTP/1.1
    Host: localhost:8181
    Connection: Upgrade
    Pragma: no-cache
    Cache-Control: no-cache
    Upgrade: websocket
    Sec-WebSocket-Version: 13
    Sec-WebSocket-Key: b6gjhT32u488lpuRwKaOWs==
  2. 服务器响应:如果服务器支持 WebSocket,它会发送一个 HTTP 响应,确认协议切换。此时,协议从 HTTP 切换到 WebSocket.
    HTTP/1.1 101 Switching Protocols
    Upgrade: websocket
    Connection: Upgrade
    Sec-WebSocket-Accept: rG8wsswmHTJ85lJgAE3M5RTmcCE=
  3. 数据传输:一旦握手成功,数据就可以通过建立的连接双向传输。WebSocket 数据包装在帧中,可以包含文本或二进制数据.
  4. 保持连接:连接将保持活动状态,直到被客户端或服务器关闭.


Cherish those who deserve it.