套接口Socket数据发送过程详解

来源:互联网 发布:深圳播音主持知乎 编辑:程序博客网 时间:2024/05/02 01:28

套接口发送数据过程,我们主要关注TCP和UDP数据发送,摘自《Unix网络网络编程》卷一第二章。

TCP数据发送过程

应用进程写数据到套接口缓冲区过程如下图:



 每一个TCP套接口有一个发送缓冲区,我们可以用SO-SNDBUF套接口选项来改变这一缓冲区的大小(7.5节)。当应用进程调用write时,内核从应用进程的缓冲区中拷贝所有数据到套接口的发送缓冲区。如果套接口的发送缓冲区容不下应用程序的所有数据(或是应用进程的缓冲区大于套接口发送缓冲区,或是套接口发送缓冲区还有其他数据),应用进程将被挂起(睡眠)。这里假设套接口是阻塞的,这是通常的缺省设置(我们将在第15章阐述非阻塞的套接口)。内核将不从write系统调用返回,直到应用进程缓冲区中的所有数据都拷贝到套接口发送缓冲区。所以从写一个TCP套接口的write调用成功返回仅仅表示我们可以重新使用应用进程的缓冲区。它并不告诉我们对方的TCP或对方应用进程已接收到数据。

UDP数据发送过程

udp数据发送过程


展示的套接口发送缓冲区用虚线框,因为它并不存在。UDP套接口有发送缓冲区大小(我们可以用SO_SNDBUF套接口选项修改),不过它仅仅是写到套接口的UDP数据报的大小上限。如果应用进程写一个大于套接口发送缓冲区大小的数据包,内核将返回一个EMSGSIZE错误。既然UDP是不可靠的,它不必保存应用程序的数据拷贝,因此无需一个真正的发送缓冲区。(应用进程的数据在沿协议向下传递时,以某种形式拷贝到内核的缓冲区,然而数据链路层在送出这些数据后将丢弃该拷贝)

UDP简单地给用户数据报安上它的8个字节的头部以构成UDP数据报,然后传递给IP。IPv4或IPv6给UDP数据报安上相应的IP头部以构成IP数据报,执行路由操作确定外出接口,然后直接把数据包加入数据链路层输出队列(如果适合于MTU),或者分片后再把每个片加入数据链路层的输出队列。如果某个UDP应用进程发送大数据报,那么它比TCP应用进程更有可能分片,因为TCP会把应用数据划分成MSS大小的块,而UDP却没有对等的手段。

写UDP套接口的write调用成功地返回表示用户写入的数据报或其所有片段已被加入数据链路层的输出队列。如果该队列没有足够的空间存放该数据报或它的某个片段,内核通常将给应用程序返回一个ENOBUFS错误。
原创粉丝点击