如何确保TCP数据包不会与其他数据包合并

时间:2013-10-27 13:54:58

标签: c# sockets networking tcp

我的程序实现了http客户端(通过继承自TCPClient),它向http服务器发送请求以获取块传输编码流(换句话说,通过HTTP的视频流)。

为了监视客户端和服务器之间的连接,我启动了后台线程,尝试将空字节(0x00)写入同一个套接字并相应地发现连接问题(如建议的here):

while (Client != null && Client.Send(ping) > 0)
    Thread.Sleep(2000);

从两个线程写入的影响是,在Wire-shark中,我有时会在同一个数据包中看到ping和HTTP请求,如下所示:

00 10 18 8d 23 ab 00 11 5d b9 e8 00 08 00 45 00  ....#...].....E.
00 b1 38 21 40 00 3e 06 77 de 0a 3f 03 3d 0a 3f  ..8!@.>.w..?.=.?
74 8d 89 7f 00 50 6b c3 45 a8 9f 76 4a 88 80 18  t....Pk.E..vJ...
13 5d a9 ad 00 00 01 01 08 0a 9c ea b6 a5 00 06  .]..............
9f 8b 47 45 54 20 2f 73 74 72 65 61 6d 2f 31 2f  ..GET /stream/1/
45 76 65 6e 74 41 20 48 54 54 50 2f 31 2e 31 0d  EventA HTTP/1.1.

当然,服务器忽略此数据包,无法看到http请求。

有没有办法写入socket并使用Send方法并确保它将在一个数据包中发送?

[编辑]

正如我从大卫和TAS的答案中可以理解的那样 - 这是不可能的。而这甚至不是TCP的运作方式。

2 个答案:

答案 0 :(得分:1)

请勿监控连接。只是尝试使用它,看看你是成功还是失败。相信我,你想要做的事情会让你感到痛苦。另一端不知道如何处理你发送的零字节。

答案 1 :(得分:0)

您的方法存在一个问题:将数据写入Web服务器就像违反了HTTP一样,可能导致服务器崩溃或断开连接。

您正在实施的客户端将不断从服务器读取数据。对read的调用将显示服务器是否关闭连接,或者如果发生超时则抛出异常。后者通常会在出现某种网络问题时发生,因为Web服务器会优雅地关闭那些连接。

更新: 暂停客户端上的传输不会阻止服务器继续发送块。如果未收到数据,则底层OS缓冲区将填满,最后将丢弃数据包。最终结果可能是服务器关闭了连接,因为它认为网络存在一些问题。

一种解决方案是继续读取块并将它们存储在缓冲区中以便以后回放。如果没有足够的内存可用,那么我将关闭连接并在用户恢复时重新连接。