服务器通信过程

2014-05-30 19:48:39   最后更新: 2014-06-18 23:05:10   访问数量:1025




下图展示了某个应用进程写数据到一个 TCP 套接字中时发生的步骤

 

每一个 TCP 套接字都有一个发送缓冲区,我们可以使用 SO_SNDBUF 套接字选项来改变这个缓冲区的大小

当某个应用进程调用 write 时,内核从该应用进程的缓冲区中复制所有数据到所写套接字的发送缓冲区,如果该套接字的发送缓冲区容不下该进程的所有数据,这个进程就会进入睡眠,直到应用进程缓冲区中的所有数据都复制到套接字发送缓冲区,内核才会从 write 系统调用中返回,但这并不意味着对端已经接收到数据,这仅仅表明我们可以重新使用原来的应用进程缓冲区了

 

发送端提取 TCP 套接字发送缓冲区中的数据并把它发送给对端 TCP,其过程基于 TCP 数据传送的所有规则

对端 TCP 必须确认收到数据,当本端接收到对端 ACK 的到达,本端才能从套接字缓冲区中丢弃已经被确认的数据,否则,将会重发缓冲区中的数据

也就是说,TCP 必须为已发送的数据保留一个副本,直到它被对端确认为止

数据包的大小最大为对端通告的 MSS 的大小,若对端没有发送 MSS 选项,则 MSS 取值为536,因为在IPv4下,最大传输单元 MTU 的值为576,而 IP 首部为20字节,TCP 首部为20字节

 

每个数据链路都有一个输出队列,如果该队列已满,新到的分组就会被丢弃,并沿着协议栈返回一个错误,TCP 马上会进行数据的重传,而应用进程并不知道这一情况

下图展示了某个应用进程些数据到一个 UDP 套接字中时发生的步骤

 

在 UDP 中并不存在套接字发送缓冲区,任何 UDP 套接字都有发送缓冲区大小,和 TCP 中一样,我们可以使用 SO_SNDBUF 套接字选项更改他,但是他仅仅是可写到该套接字的 UDP 大小上限

如果一个应用进程洗了一个大于套接字发送缓冲区大小的数据报,内核将返回该进程一个 EMSGSIZE 错误

而 UDP 是不可靠的,它不会保存应用进程数据的副本,因此不需要真正的发送缓冲区

 

发送端的 UDP 简单的给来自用户的数据报安上他的 8 字节首部以构成 UDP 数据报,然后传给 IP,IP 再给他安上相应的 IP 首部以构成 IP 数据报,然后直接把数据报加入数据链路层输出队列或者分片后再把每个片段加入数据链路层的输出队列

如果数据链路层输出队列没有足够的空间,内核就会返回 ENOBUFS 错误

下图展示了某个应用进程写数据到一个 SCTP 套接字中时发生的步骤

 

从图中可以看出,SCTP 和 TCP 是非常类似的,他们都有一个套接字发送缓冲区,我们也可以使用 SO_SNDBUF 套接字选项来更改这个缓冲区的大小

其发送和接收过程与 TCP 几乎是一样的

 

 






读书笔记      linux      unix      计算机网络      unp      unix网络编程      tcp      udp      网络编程      sctp      socket      龙潭书斋     


京ICP备15018585号