8.1 我们有两个应用程序,一个使用 TCP,一个使用 UDP。TCP 套接字的接收缓冲区中有 4096 字节的数据,UDP 套接字的接收缓冲区中有两个 2048 字节的数据报。TCP 应用程序调用 read, 指定其中第三个参数为 4096,UDP 应用程序调用 recvfrom,指定其中第三个参数也为 4096。这两个应用程序有什么差别吗?
- 有差别,TCP 返回 4096 字节数据。UDP 返回 2048 字节数据,不管应用程序请求多大,绝不返回多于一个数据报大小的数据。
- 如果协议使用可变长度套接字地址,那么 clilen 可能会太大。正确的编写方式是让使用 recvfrom 返回的 len 作为 sendto 的最后一个参数。
- 运行过几百遍了。
8.4 在一个窗口中运行 ping 程序,指定 -i 60 选项(每 60 秒发一个分组;有些系统用 -I 而不是 -i),-v 选项(输出所有接收到的 ICMP 错误)和环回地址(通常为 127.0.0.1)。我们将用该程序来观察由服务器主机返回的端口不可达 ICMP 错误。然后,在另一个窗口运行上一个习题中的客户,指定不在运行服务器的某主机的 IP 地址。将会发生什么?
- ????
- 监听套接字也许有自己的接收缓冲区,但绝不会接收数据。
8.6 直接背这个结论吧。。。我哪来的多宿主机?如果客户 bind 一个 IP 地址到它的套接字上,但是发送一个从其他接口外出的数据报,那么该数据报任然包含绑定在该套接字上的 IP 地址,即使该 IP 地址与该数据报的外出接口并不相符也不管。
8.7 编译 8.13 节中的程序并在不同的主机上运行客户和服务器。在客户程序中每次写一个数据报到套接字处放一个 printf 调用,这回改变接收到分组的百分比吗?为什么?在服务器程序中每次从套接字读一个数据报处放一个 printf 调用,这会改变接收到分组的百分比吗?为什么?
- 放 printf 太温和了,直接上 usleep,改写了 udp 服务器和 udp 客户端,可以设置在 recvfrom 和 sendto 后睡多少毫秒,多做几次实验可以看出,udp 缺乏流量控制这一个事实。当客户端发送过快,服务器来不及接收时,就会产生大量丢包。但是假如服务器接收速率超过客户端发送速率,那么就不会因为缓冲区溢出而丢包。
- UDPLackFlowControlServer.c
- UDPLackFlowControlClient_DelaySend.c
-
65536,UDP 报文段头部的长度字段是 2 字节长,最大范围可表示 0 ~ 65536 字节。但是这个字段是包含了首部和数据区域总长度的,也就是说,数据报中最大的数据量是 65536 - 8 = 65528 字节。但是因为 IPv4 数据报的头部也有 2 字节长度字段,因此留给 UDP 的只有 65508 字节数据。
-
先设置发送缓冲区大小,然后再发送,这样的话避免了出现 EMSGSIZE 的错误。以防止报文段太大装不进默认的发送缓冲区中。