我只是在调试一个非常奇怪的问题,因为从HTTP服务器下载文件时移动客户端卡住了 . 客户端运行在Sierra Wireless Q2687 GSM模块上 .
每次传输在正好13480字节(10个数据包,每个1348个有效载荷)之后挂起 . 我只看到上面提到的GSM模块的这个问题,其他客户端运行良好 .
我做了一些Wireshark调试,注意以下事项:
-
从服务器到客户端的最后一个数据包的(相对)序列号为12133,有效载荷为1348字节
-
客户端然后确认该数据包,发送的ACK序列号为13482,与预期的12133 1348 = 13481相比是逐个的
_999_在ACK之后,服务器根本不再发送数据包并且连接被卡住(我确定nginx
有更多数据要发送,检查) .
所以,对我而言,它看起来像Sierra Wireless TCP堆栈的一个一个错误 - 确认实际收到的更多数据 .
问题:
-
任何人都可以确认,序列号高于最高
(received sequence number + length)
的ACK会违反TCP规范吗? -
鉴于以上情况属实,Linux TCP堆栈如何处理这种情况? (如果没有先前的经验,TCP堆栈源代码有点难以理解,因此非常欢迎指向源代码中特定检查的指针) .
1 回答
如果数据包设置了FIN标志,那么对数据包的ACK将是序列1.所以可能只是你错过了这个标志 . 这也可以解释您没有看到更多数据,因为FIN意味着不再有数据(即连接结束) .
如果没有FIN标志,那么确实无效,我认为内核只会丢弃无效的ACK .