gpt4 book ai didi

c# - 一次发送大量数据包时,异步套接字始终读取 0 字节

转载 作者:太空宇宙 更新时间:2023-11-03 16:34:49 25 4
gpt4 key购买 nike

我研究了这么多小时并尝试了很多不同的方法来解决这个问题,但我被卡住了。我正在尝试创建一个可以从多个线程访问的异步套接字。它往往运行正常,直到我有几个线程试图在接近同一时间发送。发送没有错误,唯一的问题是当 EndReceive() 尝试读取数据时,它返回 0 字节并且套接字错误是“成功”。我读过这意味着它是正常关闭,服务器没有更多数据要发送,但我连接的服务器类型不应该发送所有数据,它不是那种类型的服务器。应该始终有要读取的数据,并且不应关闭。

我曾经发送一些 System.Threading.Timers 的线程,但我读到它们并不是完全线程安全的。我也尝试使用 System.Timers.Timer,但结果相同。我也试过只使用 1 个线程一次发送大量数据包,在两者之间休眠 100 毫秒,我会得到相同的结果。

接收代码如下。对于发送,我尝试过定期阻止 Send 和 BeginSend,但没有任何区别。

void Receive()
{
try
{
if (_datacb == null)
_datacb = new AsyncCallback(OnRecvData);

byte[] buffer = new byte[FBufferSize];
FSocket.BeginReceive(buffer, 0, FBufferSize, SocketFlags.None, _datacb, buffer);
}
catch (SocketException ex)
{
OnSocketError(ex);
}
}

void OnRecvData(IAsyncResult ar)
{
try
{
SocketError err;
int bytesRead = FSocket.EndReceive(ar, out err);

if (bytesRead == 0)
{
throw new SocketException();
}

byte[] buffer = ar.AsyncState as byte[];
FReceived.AddBytes(buffer, bytesRead);
ByteBuffer message = FReceived.GetNextMessage();
while (message != null)
{
Process(message);
message = FReceived.GetNextMessage();
}
}
catch (SocketException ex)
{
OnSocketError(ex);
}

Receive();
}

我认为可能是服务器因为发送速度太快而关闭了套接字,但实际上我有一个我在 VS2008 中制作的阻塞版本,我能够使用 50 个不同的计时器,每秒发送 1 个数据包,我没有断开连接。我在 VS2010 中尝试了几乎相同的代码,bytesRead 为 0。我还在 VS2008 中尝试了异步套接字代码,只是为了看看是否发生了奇怪的事情,但在 VS2008 中,它仍然给我 bytesRead == 0。对于不存在的阻塞代码不要断开我的连接:

tcpClient = new TcpClient(host, 443);
networkStream = tcpClient.GetStream();
mReader = new BinaryReader(networkStream);
mWriter = new BinaryWriter(networkStream);
receiveMessage = new Thread(new ThreadStart(ReceiveMessages));
receiveMessage.Start();

private void ReceiveMessages()
{
while (true)
{
if ((tcpClient != null) && (tcpClient.Connected))
{
if (tcpClient.Available >= 4)
{
if (!isConnected) isConnected = true;

try
{
ByteBuffer message = new ByteBuffer();
message.AddBytes(mReader.ReadBytes(4));
int mSize = message.ReadInt();
message.AddBytes(mReader.ReadBytes(mSize - 4));
processor.Process(message);
}
catch (Exception ex)
{
Print("Recv Msg: " + ex.Message);
}
}

Thread.Sleep(1);
}
}

发送:

mWriter.Write(send);
mWriter.Flush();

不太满意,因为它占用大量 CPU。我尝试了其他方法来像这样阻塞套接字而不使用那么多 CPU,但它们也往往会断开连接。

最佳答案

套接字不是线程安全的。参见 here

您应该同步您对套接字的访问,或者让一个线程处理所有这些(我认为这样更干净,并且还会导致更容易调试)。

关于c# - 一次发送大量数据包时,异步套接字始终读取 0 字节,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9451079/

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