【发布时间】:2010-10-01 16:13:26
【问题描述】:
我正在尝试优化一个 tcp 套接字包装器,该包装器正在与大量入站连接作斗争。我正在一个基本的聊天服务器和一个小型客户端应用程序中对其进行测试,以将客户端发送给它。这两个应用程序都位于由千兆交换机连接的单独 W2k3 服务器上。
通过反复试验,我将测试改进为 10 个以 100 毫秒间隔连接的客户端,然后在所有 10 个客户端都连接后,它们各自向服务器发送一条“进入房间”消息,再次以 100 毫秒的间隔发送。当服务器收到一条消息时,它会向发送者回复房间中每个人的列表,同时还会向房间中的其他所有人发送一条消息,告知有新来的人。
每次发送需要超过 1 秒才能完成(对于 100 多个客户端,这需要 3-4 秒),并且通过日志记录,我已经确定延迟介于 Socket.SendAync 和引发的相应事件之间。 Cpu 使用率始终很低。
我已经尝试了所有我能想到的方法,并花了几天时间在网上寻找线索,但我完全不知所措。这不正常吧?
编辑:按要求编码。我已经对其进行了一些整理,删除了不相关的计数器和日志记录等,当我试图缩小问题范围时,它目前在 kludge 之上进行了 hack。
private void DoSend(AsyncUserToken token, String msg)
{
SocketAsyncEventArgs writeEventArgs = new SocketAsyncEventArgs();
writeEventArgs.Completed += ProcessSend;
writeEventArgs.UserToken = token;
Byte[] sendBuffer = Encoding.UTF8.GetBytes(msg + LineTerminator);
writeEventArgs.SetBuffer(sendBuffer, 0, sendBuffer.Length);
Interlocked.Add(ref m_totalBytesAttemptedSend, sendBuffer.Length);
Logger2.log(Logger2.Debug5, token.ConnectionId, "Total Bytes attempted: " + m_totalBytesAttemptedSend);
bool willRaiseEvent = true;
try
{
willRaiseEvent = token.Socket.SendAsync(writeEventArgs);
}
catch (Exception e)
{
Logger2.log(Logger2.Debug2, token.ConnectionId, e.Message);
writeEventArgs.Dispose();
}
if (!willRaiseEvent)
{
ProcessSend(null, writeEventArgs);
}
}
private void ProcessSend(Object sender, SocketAsyncEventArgs e)
{
AsyncUserToken token = (AsyncUserToken)e.UserToken;
Logger2.log(Logger2.Debug5, token.ConnectionId, "Send Complete");
if (e.SocketError == SocketError.Success)
{
Interlocked.Add(ref m_totalBytesSent, e.BytesTransferred);
Logger2.log(Logger2.Debug5, ((AsyncUserToken)e.UserToken).ConnectionId, "Total Bytes sent: " + m_totalBytesSent);
}
else
{
if (token.Connected)
{
CloseClientSocket(token);
}
}
e.Dispose();
}
【问题讨论】:
-
你能发布一些相关的代码吗?很难猜测套接字问题。
-
你有 SocketAsyncEventArgs 池吗?
-
Eric - 我目前没有汇集 SocketAysncEventArgs,但计划稍后添加。但是,我在创建 SocketAysncEventArgs 并填充其缓冲区后记录开始时间,并将结束时间记录为回调中的第一个操作,所以虽然我知道它效率低下,但它不应该影响这部分执行?跨度>
-
Zor - 今天晚些时候我会得到一些代码 sn-ps
标签: c# performance sockets asynchronous