gpt4 book ai didi

c# - Socket EndReceive 命令/数据问题

转载 作者:可可西里 更新时间:2023-11-01 02:54:57 25 4
gpt4 key购买 nike

背景:

我正在编写的应用程序使用异步套接字(使用 BeginSend、EndSend、BeginReceive、EndReceive)在彼此之间发送数据。 IPV4 上的套接字是 TCP,没有套接字标志。

它使用发送 4 字节 (int) 消息的系统,后跟一条消息,其长度在前一条消息中指定。我使用处理 MessageLength 和 MessageBody 的函数助手。流程是这样的

  1. 开始接收()
  2. 结束接收()
  3. MessageLengthReceived()
  4. 开始接收()
  5. MessageBodyReceived()

问题:

当我以 16kb 的 block 发送文件数据时,问题就来了(还有一个额外的小开销:offset、pieceIndex 等)。有时,在接收 MessageLength 时,它会从前一条消息中的随机部分接收到一个数据,而不是实际的消息长度。这个问题的部分原因是它并不总是发生在设定的偏移量(例如文件/片段/16 kb block 的开头或结尾)并且可能发生在任何文件上,但如果我发送更多文件/更大的文件会发生更多.

发送的内部消息(例如 RequestMessages)从未遇到过此问题。所有内部消息都小于 100 字节。

我已经尝试等待文件 block 完全保存后再请求另一个 block ,但它仍然失败。我也试过限制一次发送多少 block ,但这只能解决使用 127.0.0.1(本地客户端)而不是跨网络(LAN)时的问题。

我花了几个小时检查我的应用程序以查看是否有任何问题,但我还没有看到它会在哪里发送错误的数据作为 header 。这个问题似乎总是在两个客户端的发送和接收之间。是否有我应该使用的套接字/发送方法的设置?或者它可能是某种竞争条件(我考虑过竞争条件,但数据可以随机出现在文件中的任何位置这一事实让我重新考虑了这一点)。

最佳答案

从这个问题来看,我猜你正在处理的问题是在 MonoTorrent 库中。

我自己没遇到过这样的问题。通过查看代码,我认为接收部分已经订购,因为网络 IO 在处理完第一条消息之前不会尝试接收第二条消息。 PieceMessages 的写请求也在 DiskIO 中排队,所以这应该不是问题。

但是,在发送过程中,ProcessQueue 函数可以从多个地方调用。并且 ProcessQueue 间接调用的 EnqueueSendMessage 实际上并未将消息排队到任何队列。它只是简单地调用 Socket.BeginSend。不知道Socket.BeginSend()里面有没有队列机制。如果没有,当多个线程试图使同一个套接字“开始发送”不同的数据时,这可能会带来一些问题。

关于c# - Socket EndReceive 命令/数据问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10357129/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com