Skip to content

Latest commit

 

History

History
43 lines (20 loc) · 3.83 KB

File metadata and controls

43 lines (20 loc) · 3.83 KB

8.1 我们有两个应用程序,一个使用 TCP,一个使用 UDP。TCP 套接字的接收缓冲区中有 4096 字节的数据,UDP 套接字的接收缓冲区中有两个 2048 字节的数据报。TCP 应用程序调用 read, 指定其中第三个参数为 4096,UDP 应用程序调用 recvfrom,指定其中第三个参数也为 4096。这两个应用程序有什么差别吗?

  • 有差别,TCP 返回 4096 字节数据。UDP 返回 2048 字节数据,不管应用程序请求多大,绝不返回多于一个数据报大小的数据。

8.2 在图 8-4 中,如果我们用 clilen 来代替 sendto 的最后一个参数(它原本是 len),将会发生什么?

  • 如果协议使用可变长度套接字地址,那么 clilen 可能会太大。正确的编写方式是让使用 recvfrom 返回的 len 作为 sendto 的最后一个参数。

8.3 编译并运行图 8-3 及图 8-4 的 UDP 服务器程序和图 8-7 及图 8-8 的 UDP 客户程序。验证一下客户与服务器能一起工作。

  • 运行过几百遍了。

8.4 在一个窗口中运行 ping 程序,指定 -i 60 选项(每 60 秒发一个分组;有些系统用 -I 而不是 -i),-v 选项(输出所有接收到的 ICMP 错误)和环回地址(通常为 127.0.0.1)。我们将用该程序来观察由服务器主机返回的端口不可达 ICMP 错误。然后,在另一个窗口运行上一个习题中的客户,指定不在运行服务器的某主机的 IP 地址。将会发生什么?

  • ????

8.5 对于图 8-5 我们说过每个已连接 TCP 套接字都有自己的套接字接收缓冲区。监听套接字情况怎么样?你认为它有自己的套接字接收缓冲区吗?

  • 监听套接字也许有自己的接收缓冲区,但绝不会接收数据。

8.6 直接背这个结论吧。。。我哪来的多宿主机?如果客户 bind 一个 IP 地址到它的套接字上,但是发送一个从其他接口外出的数据报,那么该数据报任然包含绑定在该套接字上的 IP 地址,即使该 IP 地址与该数据报的外出接口并不相符也不管。

8.7 编译 8.13 节中的程序并在不同的主机上运行客户和服务器。在客户程序中每次写一个数据报到套接字处放一个 printf 调用,这回改变接收到分组的百分比吗?为什么?在服务器程序中每次从套接字读一个数据报处放一个 printf 调用,这会改变接收到分组的百分比吗?为什么?

  • 放 printf 太温和了,直接上 usleep,改写了 udp 服务器和 udp 客户端,可以设置在 recvfrom 和 sendto 后睡多少毫秒,多做几次实验可以看出,udp 缺乏流量控制这一个事实。当客户端发送过快,服务器来不及接收时,就会产生大量丢包。但是假如服务器接收速率超过客户端发送速率,那么就不会因为缓冲区溢出而丢包。
  • UDPLackFlowControlServer.c
  • UDPLackFlowControlClient_DelaySend.c

8.8 对于 UDP/IPv4 套接字,可传递给 sendto 的最大长度是多少;也就是说,可装填在一个 UDP/IPv4 数据报中的最大数据量是多少?UDP/IPv6 又有什么不同?

  • 65536,UDP 报文段头部的长度字段是 2 字节长,最大范围可表示 0 ~ 65536 字节。但是这个字段是包含了首部和数据区域总长度的,也就是说,数据报中最大的数据量是 65536 - 8 = 65528 字节。但是因为 IPv4 数据报的头部也有 2 字节长度字段,因此留给 UDP 的只有 65508 字节数据。

  • SendBigDataByUDP.c

  • 先设置发送缓冲区大小,然后再发送,这样的话避免了出现 EMSGSIZE 的错误。以防止报文段太大装不进默认的发送缓冲区中。

8.9 通过对 UDP 套接字使用 IP_RECVDSTADDR 套接字选项,把图 8-25 的程序修改为符合 RFC 1122。