亲历网络节点吞数据

来源:互联网 发布:java log方法 编辑:程序博客网 时间:2024/05/02 00:50

之前做一个小练习时遇到的问题,挺有意思的,还写了个帖子问了下别人。下面是这个帖子的内容,说的还是比较的清楚的。

关于网络节点吞数据的问题

为什么会提出这样一个问题?

原因是在看《Unix 网络编程(卷1)》这本书的第六章时,为了做一个简单的练习,就把第六章基于 select 函数实现的回射服务器和相应的客户端自己实现了下,然后在测试时程序就出现了诡异的问题。

测试时采用如下方式:

  • 回射服务器运行在一台美国 VPS 上,系统是 CentOS 6 32 bit

    [root@TestServer bin]# ./server &
  • 客户端运行在内网的一台机器上,系统是 OS X 10.10.3,另外运行时将标准输入重定向到了一个随手抓来的测试文件 aclocal.m4。

    HDMdeMacBook-Pro:bin HDM$ ./client 216.127.176.164 < ~/Downloads/gdb-7.9.1/readline/aclocal.m4

结果就发现测试过程中会偶尔会出现如下问题:

  1. 回射服务器阻塞于 select 调用,服务器端的连接套接字连接处于如下状态:
    server_netstat
  2. 客户端阻塞于 select 调用,客户端的连接套接字处于如下状态:
    client_netstat
  3. 客户端目前接受的数据只有它发送给服务器端的数据的一部分

综合以上几点,问题来了,首先服务器端套接字和客户端套接字的状态是矛盾的。FIN_WAIT_1 表示客户端执行了主动关闭,已经发送了 FIN 分节,目前正在等待这个 FIN 分节的 ACK 分节;然而,LAST_ACK 却表示服务器端已经接受到了客户端发送的 FIN 分节,且已发送了对这个 FIN 分节进行相应的 ACK 分节,然后又发送了自己的 FIN 分节,现在正在等待这个 FIN 的 ACK 分节。两者的状态完全不一致。而且,服务端套接字处于 LAST_ACK 说明他已经把客户端发送给她的数据全部回射了,但问题是客户端目前只接收到了一部分。

为什么呢?该开始我觉得是代码有问题,可就那么几行代码,真看不出有什么问题。后来,我就怀疑是不是服务器端和客户端中间的网络节点吞了数据。于是我同时抓了服务器端和客户端的数据。下面是分别从服务器端和客户端抓的数据包文件。

  • client.pcapng 客户端的数据包文件
  • server.pcap 服务器端的数据包文件

对两个数据包文件查看后发现。回射服务器确实已经回射了客户端发送的所有数据。而客户端目前确实只接收到了它发送给服务器端的数据的一部分。跟最初的猜测一样。

额,总是虽然感觉事实就是这样,但感觉还是很诡异,所以问下大家的意见,求大牛解答。

相关文件

代码实现和相关的测试文件在这里 https://github.com/HDM1991/Practice/tree/master/IOMultiplexingTest

0 0
原创粉丝点击