套接字端接收订单/数据问题
本文关键字:数据 问题 端接 套接字 | 更新日期: 2023-09-27 18:32:43
背景:
我正在编程的应用程序使用异步套接字(使用BeginSend,EndSend,BeginReceive,EndReceive(在彼此之间发送数据。套接字是 TCP,没有套接字标志,在 IPV4 上。
它使用发送 4 字节 (int( 消息的系统,后跟具有上一条消息中指定的长度的消息。我使用处理 MessageLength 和 MessageBody 的函数助手。流程是这样的
- BeginReceive((
- EndReceive((
- 消息长度接收((
- BeginReceive((
- MessageBodyReceived((
问题:
当我以 16kb 的块发送文件数据时,问题就出现了(还有一个额外的小开销:偏移量、pieceIndex 等(。有时,在接收 MessageLength 时,它会从上一条消息中的随机部分接收数据,而不是实际的消息长度。这个问题的一部分是它并不总是发生在设定的偏移量(例如文件/片段/16 kb块的开头或结尾(,并且可能发生在任何文件中,但是如果我发送更多文件/更大的文件,则会发生更多。
发送的内部消息(例如请求消息(从未遇到此问题。所有内部消息都<100 字节
。我尝试在请求另一个块之前等待文件块完全保存,但仍然失败。我还尝试限制一次发送的块数,但这只能解决使用 127.0.0.1(本地客户端(而不是跨网络 (LAN( 时的问题。
我花了几个小时浏览我的应用程序以查看是否存在任何问题,但我还没有看到它会将错误的数据作为标头发送。问题似乎总是在两个客户端的发送和接收之间。是否有我应该使用的套接字/发送方法的设置?或者可能是某种竞争条件(我想到了竞争条件,但数据可以在文件中的任何地方随机存在这一事实让我重新考虑了这一点(。
从这个问题来看,我想你正在处理的问题在 MonoTorrent 库内。
我自己从未遇到过这样的问题。 通过查看代码,我认为接收部分已经订购,因为网络 IO 不会尝试接收第二条消息,直到处理完第一条消息。PieceMessages的写入请求也在DiskIO中排队,所以这应该不是问题。
但是,在发送过程中,可以从多个位置调用 ProcessQueue 函数。 而 ProcessQueue 间接调用的 EnqueueSendMessage 实际上并没有将消息排队到任何队列。 它只是简单地调用 Socket.BeginSend。我不知道 Socket.BeginSend(( 内部是否有任何队列机制。如果没有,当多个线程尝试使同一套接字"开始发送"不同的数据时,这可能会带来一些问题。