我现在完全糊涂了。
编辑:好的,没关系。 Python套接字现在也开始这样做了。
编辑2:嗯,不太确定这是否会导致高CPU使用率,但随机的是。有没有一种有效的方法来找出导致使用量激增的原因?这个项目有点大,有各种各样的线程。
我有一个异步服务器,它监听并等待传入连接,然后使它们保持活动状态并等待套接字刷新并提供服务器数据。它仅在用户想要关闭套接字时关闭。
然而,每当我让一个插座&流保持连接,它开始变得混乱并开始在无限循环中发送空数据...它可能需要15秒到超过一分钟才能开始变坏。如果我让它真的真的很长时间,它会开始导致非常高的CPU使用率。
除了高CPU使用率,奇怪的是,一切都按预期工作;消息发送&收到罚款。
这是我的回读函数:
protected void ReadCallback(IAsyncResult ar)
{
StateObject state = (StateObject)ar.AsyncState;
Socket handler = state.SocketHandle;
try
{
int bytesRead = (state.BytesRead += handler.EndReceive(ar)), offset = 0;
string line = m_Encoder.GetString(state.Buffer, 0, bytesRead);
if ( state.Buddy != null )
Console.WriteLine(state.Buddy.Address);
if (bytesRead > 0)
{
Console.WriteLine("!!!");
/* A complete request? */
if (line.EndsWith("\n") || line.EndsWith("\x00"))
{
string[] lines = line.Split('\n'); // ... *facepalm*
foreach (string ln in lines)
this.MessageReceieved(ln, state);
state.Buffer = new byte[StateObject.BUFFER_SIZE];
state.BytesRead = 0; // reset
}
/* Incomplete; resize the array to accommodate more data... */
else
{
offset = bytesRead;
Array.Resize<byte>(ref state.Buffer, bytesRead + StateObject.BUFFER_SIZE);
}
}
if (handler != null && handler.Connected )
handler.BeginReceive(state.Buffer, offset, state.Buffer.Length - offset, SocketFlags.None, new AsyncCallback(ReadCallback), state);
}
catch (SocketException)
{
if (state.Buddy != null)
state.Buddy.Kill();
else
handler.Close();
}
}
我知道这是通过调用BeginReceive以某种方式引起的,但我不知道如何保持连接活着。
答案 0 :(得分:2)
该代码中没有任何内容可以使它变得混乱。
我确实看到了一些问题。
连接检测
无需检查插座是否已连接。您可以在接收回调中以两种方式检测断开连接:
EndReceive
我建议你在EndReceive
之后做的第一件事是检查返回值并相应地处理断开连接。它使代码更清晰。
如果收到0个字节,您的代码将无法执行任何操作。 handler
将停止接收并仍然认为连接已打开。
缓冲区处理
你的缓冲区处理非常有效。不要每次调整缓冲区大小。它会降低你的服务器速度。从开始分配大缓冲区。
字符串处理
每次收到某些内容时都不要构建字符串。在新行之后检查字节缓冲区内部或者替换为null。然后构建一个字符串,只根据需要使它变大。您可能会收到更多仅包含消息的字节(例如,一条半消息)