解决方案 »
- c# 获取控制台应用程序输出的结果
- .net没有代码即时提示的一个非常奇怪的问题
- 超难问题,求解决方法!
- 关于控件visible隐藏出现的问题!
- 请问:我用TlbImp.exe Excel9.olb命令后,为什么只有Excel.DLL和Office.DLL两个文件?VBIDE.dll文件在哪儿?
- C#中提示InvalidArgument = "4" 的值对于"index"无效,是哪的错误?
- DataGridViewComboBoxColumn列如何让其可录入编辑
- datagrid的分页怎么才执行?
- 问:有Oracle客户端的应用程序,如何配置oracle连接?分不够可以再加!
- 连接的问题
- [WCF] 服务端上传大文件
- winform
private void StartAccept(SocketAsyncEventArgs acceptEventArg)
{
if (!m_bRunning)
{
return;
} if (acceptEventArg == null)
{
acceptEventArg = new SocketAsyncEventArgs();
AsyncState state = new AsyncState();
state.Sock = m_sListen;
state.Async = true;
acceptEventArg.UserToken = state;
acceptEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(EventCompleted);
}
else
{
acceptEventArg.AcceptSocket = null;
} // 查询等待是否有空闲socket资源
m_semaMaxOnline.WaitOne(); lock (m_SocketPool)
{
try
{
acceptEventArg.AcceptSocket = m_SocketPool.Pop();
}
catch { }
} if (acceptEventArg.AcceptSocket == null)
{
return;
} try
{
AsyncState state = (AsyncState)acceptEventArg.UserToken;
state.Async = m_sListen.AcceptAsync(acceptEventArg);
if (!state.Async)
{
AcceptHandler(acceptEventArg);
}
}
catch
{
lock (m_SocketPool)
{
m_SocketPool.Push(acceptEventArg.AcceptSocket);
}
StartAccept(acceptEventArg);
}
}private void EventCompleted(object sender, SocketAsyncEventArgs e)
{
if (e == null)
{
return;
} switch (e.LastOperation)
{
case SocketAsyncOperation.Accept:
AcceptHandler(e);
break;
case SocketAsyncOperation.Receive:
ReceiveHandler(e);
break;
case SocketAsyncOperation.Send:
SendHandler(e);
break;
default:
m_strErrMsg = String.Format("非accept、receive或send的操作:{0}", e.LastOperation);
break;
}
}private void AcceptHandler(SocketAsyncEventArgs e)
{
SocketAsyncEventArgs readEventArgs = null;
lock (m_rwEventArgsPool)
{
readEventArgs = m_rwEventArgsPool.Pop();
} if (readEventArgs == null)
{
e.AcceptSocket.Shutdown(SocketShutdown.Both);
lock (m_SocketPool)
{
m_SocketPool.Push(e.AcceptSocket);
} StartAccept(e); return;
}
readEventArgs.AcceptSocket = e.AcceptSocket; if (e.AcceptSocket != null)
{
Client client = m_ClientPool.Pop();
client.Sock = e.AcceptSocket;
client.EventArgs = readEventArgs;
client.HeartBeat = DateTime.Now;
client.Sock = e.AcceptSocket;
lock (m_dicSockClient)
{
if (m_dicSockClient.ContainsKey(client.Sock))
{
m_dicSockClient.Remove(client.Sock);
}
m_dicSockClient.Add(client.Sock, client);
}
} if (m_bufferPool.SetBuffer(readEventArgs))
{
AsyncState state = (AsyncState)readEventArgs.UserToken;
try
{
state.Async = readEventArgs.AcceptSocket.ReceiveAsync(readEventArgs);
if (!state.Async)
{
ReceiveHandler(readEventArgs);
}
}
catch
{
CloseClient(readEventArgs);
}
} StartAccept(e);
}
不行的话只好把整个accept改成全循环了。。
在循环开始的时候 reset,
在complete或者收到连接后Set,
在AcceptAsync之后 WaitOne.
你的“阻塞”式代码,本来就是一个“披着多线程外衣、实际上偷运的是循环思路”的代码。你始终没有搞明白多线程异步代码应该如何写。而且msdn上的类似代码也是误导了你,它也是同样问题。当接收到Accept之后,必须创建一个新的 SocketAsyncEventArgs 实例用来维持与当前客户端的一系列持续的 Reveive操作。一旦创建这个之后,就再次异步等待当前 SocketAsyncEventArgs 实例的下一个 Accept 操作。总共只有(大致)两条代码,却让你写成了几十条代码这么巨大的一个程序。