我正在尝试用C#构建套接字服务器,我遇到的一个问题是,当我将 AsyncCallback 传递给我的套接字的 BeginReceive 方法时,回调就是调用太快,当我读到IAsyncResult的 AsyncState 属性时,我变为null。
我以为我通过添加
来“修复”了这个问题.AsyncWaitHandle.WaitOne(100);
但问题仍然存在。谁能说清楚我做错了什么?
我的代码如下(缩写):
private void Main(){
_listener.BeginAccept(new AsyncCallback(HandleConnection), null);
}
private void HandleConnection(IAsyncResult status)
{
SocketError socketRecieveError;
_connectionSocket = _listener.EndAccept(status);
_connectionSocket.BeginReceive(_receivedDataBuffer, 0, _receivedDataBuffer.Length, 0, out socketRecieveError,
new AsyncCallback(HandleHandshake), _connectionSocket.Available);
if(socketRecieveError != SocketError.Success)
_logger.Log("Socket error: " + socketRecieveError);
}
private void HandleHandshake(IAsyncResult status)
{
status.AsyncWaitHandle.WaitOne(1000);
int handshakeLength;
try
{
handshakeLength = Convert.ToInt32(status.AsyncState); // <--- BOOOM
}
catch (Exception ex)
{
_logger.Log(ex.Message);
}
..............
}
答案 0 :(得分:1)
IAsyncResult的AsyncState属性包含用户定义的对象,该对象包含有关异步操作(MSDN)的信息。这是在调用异步操作时作为参数“state”提供的同一对象。
在您的代码中,您将_connectionSocket.Available作为用户状态提供。我想你想为你的回调方法提供收到的字节数?这不是正确的方法。
这是正确的方法:
private void HandleConnection(IAsyncResult status)
{
SocketError socketRecieveError;
_connectionSocket = _listener.EndAccept(status);
_connectionSocket.BeginReceive(_receivedDataBuffer, 0, _receivedDataBuffer.Length, 0, out socketRecieveError, new AsyncCallback(HandleHandshake), null);
if(socketRecieveError != SocketError.Success)
_logger.Log("Socket error: " + socketRecieveError);
}
private void HandleHandshake(IAsyncResult ar)
{
int bytesReceived = _connectionSocket.EndReceive(ar);
....
}