Skip to content

Latest commit

 

History

History
100 lines (78 loc) · 5.14 KB

习题.md

File metadata and controls

100 lines (78 loc) · 5.14 KB

1、按 1.9 节末尾的步骤找出你自己的网络拓扑的信息

  • 首先,使用 ifconfig 或者 netstat -ni 得到接口信息
en0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
ether a4:5e:60:ef:99:4d 
inet6 fe80::8bf:586e:d743:ddc0%en0 prefixlen 64 secured scopeid 0x5 
inet 192.168.1.100 netmask 0xffffff00 broadcast 192.168.1.255
nd6 options=201<PERFORMNUD,DAD>
media: autoselect
status: active
  • 从中可以看出,广播地址是 192.168.1.255
  • 接下来通过 ping 192.168.1.255 来获取该子网的网络拓扑
progs git:(master) ✗ ping 192.168.1.255
PING 192.168.1.255 (192.168.1.255): 56 data bytes
64 bytes from 192.168.1.100: icmp_seq=0 ttl=64 time=0.175 ms
64 bytes from 192.168.1.1: icmp_seq=0 ttl=64 time=1.841 ms
64 bytes from 192.168.1.100: icmp_seq=1 ttl=64 time=0.078 ms
64 bytes from 192.168.1.1: icmp_seq=1 ttl=64 time=0.848 ms
64 bytes from 192.168.1.101: icmp_seq=1 ttl=64 time=27.796 ms
64 bytes from 192.168.1.100: icmp_seq=2 ttl=64 time=0.167 ms
64 bytes from 192.168.1.1: icmp_seq=2 ttl=64 time=2.884 ms
64 bytes from 192.168.1.101: icmp_seq=2 ttl=64 time=47.149 ms
64 bytes from 192.168.1.100: icmp_seq=3 ttl=64 time=0.077 ms
64 bytes from 192.168.1.1: icmp_seq=3 ttl=64 time=2.238 ms
64 bytes from 192.168.1.100: icmp_seq=4 ttl=64 time=0.071 ms
64 bytes from 192.168.1.1: icmp_seq=4 ttl=64 time=2.053 ms
64 bytes from 192.168.1.101: icmp_seq=4 ttl=64 time=93.485 ms
^C
--- 192.168.1.255 ping statistics ---
5 packets transmitted, 5 packets received, +8 duplicates, 0.0% packet loss
round-trip min/avg/max/stddev = 0.071/13.759/93.485/26.741 ms
  • 从中可以看出,在该子网中共有 3 个 IP 地址,其中 192.168.1.1 是路由器,剩下的 101100 分别是电脑和手机两个连上了 WIFI 的设备。

2、获取本书示例的源代码,编译并测试图 1-5 所示的 TCP 时间获取客户程序。运行这个程序若干次,每次以不同 IP 地址作为命令行参数。

3、把图 1-5 中的 socket 的第一参数改为 9999。编译并运行这个程序。结果如何?找出对应于所属楚出错的 error 值。你如何找到关于这个错误的更多信息?

progs git:(master) ✗ cc Practice_03.c && ./a.out 20001
socket fd create fail!: Address family not supported by protocol family

4、修改图 1-5 中的循环,加入一个计数器,累计 read 返回大于零值的次数。在终止前属楚这个计数器值。编译并运行你的新客户程序。

  • Practice_04.c

  • ⚠️ 为什么把 MAXLINE 改的比较小就会卡死??比如改为 3 就会阻塞在 read 调用上。

progs git:(master) ✗ cc Practice_04.c && ./a.out 20013
 connect succ!
 04 JAN 2019 23:38:56 CST
 MAXLINE = 8, counter = 4
progs git:(master) ✗ cc Practice_04.c && ./a.out 20013
 connect succ!
 04 JAN 2019 23:39:37 CST
 MAXLINE = 20, counter = 2

5、按下述步骤修改图 1-9 中的程序,首先,把赋予 sin_port 的端口号从 13 改为 9999。然后把 write 的单一调用改为循环调用,每次写出结果字符串的一个字节。编译修改后的服务器程序并在后台启动执行。接着修改前一道习题中的客户程序(它在终止前输出计数器值),把赋予 sin_port 的端口号从 13 改为 9999.启动这个客户程序,指定运行修改后的服务器程序的主机的 IP 地址作为命令行参数。客户程序计数器的输出值是多少?如果可能,在不同主机上运行这个客户与服务器程序。

progs git:(master) ✗ ./a.out 20001
connect succ!
 Fri Jan  4 23:56:40 2019
 
 MAXLINE = 1024, counter = 2
  • write 了很多次,但是从 Wireshake 抓包结果来看,只发送了一两次。

  • 当 while 的每次迭代中 write 后 sleep 1 秒的话,结果如下:

progs git:(master) ✗ ./a.out 20001
 connect succ!
 Fri Jan  4 23:56:40 2019
 
 MAXLINE = 1024, counter = 27
  • write 了很多次,并且从 Wireshake 抓包结果看起来,发送和接收的次数一样多。

  • 总结,TCP 发送数据时,先把数据复制到发送缓冲区,尽可能的等待缓冲区多充满一些,以便在一个 RTT 内发送多一些数据,比如一次性能发送一个 MSS 那岂不是美滋滋,但也不能一直等着应用层充满发送缓冲区,因此会设置一个最大等待时间,到点准时打包发出。