概述

焦点是TCP UDP SCTP,UDP是简单的不可靠的数据报文协议,TCP是复杂可靠的字节流协议,SCTP支持消息边界,传输级别多宿和头段阻塞最小的

总图

网络编程(一)传输层

  1. IPv4 使用32位地址,为TCP UDP SCTP ICMP IGMP 提供分组递送服务
  2. IPv6使用128位地址
  3. TCP面向连接,全双工,关注确认、超时、重传、可以使用v4和v6,使用流套接字
  4. UDP 无链接,使用数据报套接字,不保证传输到
  5. SCTP 流控制传输协议, 全双工面向链接,
  6. ICMP 网际控制消息协议 处理在路由器和主机间流通的错误和控制消息
  7. ARP 地址解析,将IPv4地址映射为硬件地址
  8. IGMP 网际组管理协议,用于多播

UDP

  1. 是无连接的,创建一个套接字发送数据,然后可以马上用同一个套接字发送数据给另一个服务器
  2. 不可靠传输,不保证报文到达最终目的地,不保证先后顺序不变,也不保证每个数据报只到达一次,
  3. 传输的是报文流,报文就是记录边界,报文长度会随数据一同传递给接受端
  4. 为了确保到达目的地,往往添加来自对端的确认,本段的超时重传。

TCP

  1. 面向连接的,开始通信前要和给定服务器建立连接,然后终止链接
  2. 可靠传输,传输过程要求对段返回确认,否则自动重传数据。
  3. TCP根据字节对应的***对数据进行排序,这样接收端可以根据***重排数据,或者丢弃重复数据。
  4. 提供流量控制,告知对段自己能够接收的数据大小,该窗口指出缓冲区中的可用空间。窗口是动态变化的,接收数据时,窗口大小减小,应用从缓冲区读取数据时,窗口增大。若窗口大小为0,说明缓冲区满了。

SCTP

  1. 在C/S之间提供关联,并提供可靠性,排序,流量控制,关联是指两个系统之间的通信,而不止一个IP地址
  2. SCTP面向消息的,提供按顺序传输功能,发送段将长度写入每个消息
  3. 可在端点之间提供多个流,每个流各自可靠地递送消息。一个消息的丢失不会阻塞同一关联其他流上消息的传递,与TCP正好相反
  4. 多宿,在同一个关联内支持多个IP地址,

TCP的建立和终止

握手

  1. 服务器准备连接,通常经过socket() bind() listern()函数完成
  2. 客户端调用connect()主动打开, 同时发送一个SYN (同步)给服务器,并标记seq,所在的报文只有IP首部,TCP首部和选项,进入SYN_SENT
  3. 服务器返回一个SYN,同时包含服务器接受到的seq,和ACK,进入SYN_RCVD
  4. 客户返回一个ACK,此时connect()返回,ACK是上次接收的seq+1,发送后客户建立连接,服务器接受到ACK后也建立连接,此时accept()返回
    SYN占据一个字节的***空间,所以每个SYN中对应的ACK的序号就是SYN的初始***+1

TCP选项

  1. MSS 通告最大分节大小,就是在本连接的每个TCP分节接受的最大数据量,发送端使用MSS作为最大大小
  2. 窗口规模选项,(前提是两个系统必须都支持),默认最大65535,可扩展到接近1gb
  3. 时间戳选项

终止

  1. 客户端调用close() 发送一个FIN分节,即执行主动关闭,进入FIN_WAIT_1
  2. 接受到FIN的服务器 返回ACK,之后客户端进入FIN_WAIT_2,服务器将终止连接传递给应用进程,进入CLOSE_WAIT
  3. 一段时间后服务器调用close(),再次发送FIN 进入LAST_ACK
  4. 客户端接受到FIN后,发送ACK对这个FIN进行确认 ,进入TIME_WAIT等待2MSL后关闭连接
    需要注意的是,被动关闭端有可能将FIN和ACK进行合并

对于TIME_WAIT,经历的时间是2×IP数据报在网络中存在的最长时间,它的作用是

  1. 实现TCP连接正常关闭,如果客户端最终的ACK丢失,服务器会重发FIN,这时在TIME_WAIT中的客户端就可以重发ACK,避免不正常关闭
  2. 使得老的分节(包括一端的请求和另一端的回复)在网络中消失,避免新的连接收到老的分节。

端口

  1. 0~1023是IANA众所周知端口,1024~49151是注册端口。49152~65535是动态端口
  2. 套接字对定义了连接的两个端点,<本地IP,本地TCP端口,远程IP,远程TCP端口>,ip地址+端口号成为套接字
  3. {*:21,*:*}这个套接字对在任意本地地址21端口等待连接请求,服务器可指定接受到特定本地接口的外来连接,选择一个或者任意一个,服务器不能指定地址清单。任意地址即INADDR_ANY
  4. 服务器接收连接时,fork一个子进程接受请求,子进程中拥有的是已连接套接字而父进程中是监听套接字。TCP无法通过目的端口号来分离不同分节,必须查看套接字对的所有四个元素。

缓冲区大小

  1. IPv4最大65535字节,IPv6 65575字节,它有一个特大净荷来扩展净荷长度字段到32位,(默认16位)
  2. 以太网的MTU为1500, IPv4最少MTU是68字节(20固定长度+最多40选项),IPv6要求最少1280字节。路径MTU指两个主机之间最小的MTU,两个主机相反方向MTU可以不一致
  3. 如果IP数据报超过了MTU,v4和v6都会进行分片,v4主机对产生的数据报分片,v4路由对转发的分片,v6主机对产生的分片,v6路由不对转发的分片
  4. 如果DF位被设置,则即使超过了MTU也不进行分片,如果v4路由接收到了超过MTU且DF位设置的数据报,产生一个出错消息。因此它被用来探测路径上MTU,如果设置DF,且及收到了ICMP出错报文,就减小MTU再重新发送
  5. v4和v6定义了最小缓冲区大小,是任何实现都必须保证支持的最小数据报大小,v4是576字节,v6是1500字节,
  6. TCP的MSS通告每个分节最大TCP数据量,往往是MTU-IP首部-TCP首部,IPv4 1460, IPv6 1440,在TCP的MSS选项中,最大值为65535,这对IPv4适用,但对IPv6:(1)无特大净荷的,TCP最大数据量65515 (2) 有特大净荷选项,对端通告MSS 65535,则数据报大小为路径MTU

TCP输出

  1. 每个TCP套接字有发送缓冲区,通过SO_SNDBUF更改缓冲区大小,调用write时内核从应用程序缓冲区复制数据到套接字缓冲区,如果套接字缓冲区大小不足,则应用程序阻塞,直到全部数据复制到套接字缓冲区。故write返回只说明应用程序缓冲区可使用,不代表TCP对端接受到数据。
  2. TCP提取套接字缓冲区并发送对端,收到ACK后才能从发送缓冲区丢弃数据,TCP需要为已经发送的数据保留副本,直到被对端确认
  3. TCP以MSS或者更小的块将数据传给IP,并添加TCP首部,MSS为对端通告值或者536(576-20IP首部-20TCP首部)IP添加IP首部,按照地址查找路由,传输给数据链路,IP可能进行分片,但是MSS可以避免分片。

UDP输出

  1. UDP套接字有发送缓冲区大小,但仅仅是UDP数据报的大小上限。如果应用写大于套接字发送缓冲区大小的数据报,内核返回EMSGSIZE错误,UDP不必保存发送数据的副本,就不需要一个实际的发送缓冲区
  2. UDP为用户数据加上UDP头传递给IP,IP添加IP首部,然后传输给数据链路,如果UDP发送了大于MTU的数据报,有可能会被IP分片。(TCP可以通过MSS来避免分片)
  3. 写一个套接字成功表示数据报已经被加入到数据链路层的输出队列,如果队列没有足够的空间,内核通常返回ENOBUFS

常见协议

网络编程(一)传输层

TCP滑动窗口

  1. TCP两端交换信息如***,ACK,窗口大小,发送段调节窗口大小控制发送,窗口大小字段长16位,想对于ACK有一个字节偏移量,位于TCP头中
  2. TCP连接维护一对窗口,发送端分为已发送已确认、已发送未确认、尚未发送、不允许发送四个部分,收到对应窗口左端***的ACK时,窗口左端移动。接收端分为已接收已确认、允许接收、不允许接收,收到对应窗口左端***的数据并发送ACK后,窗口滑动。
  3. 发送端通过ACK可以得知下一个要发送的***和当前接收端的窗口大小(进而实现了流量控制)。
  4. 在接收端零窗口情况下,发送端采用一个计时器询问接收端窗口是否增长,强制要求接收端返回ACK

相关文章: