【发布时间】:2017-09-26 21:57:29
【问题描述】:
我正在构建一个基于服务器和客户端的应用程序,它通过套接字(典型的东西)进行通信。
预期的功能是客户端连接,它们来回发送一些数据,然后客户端关闭连接。一段时间后,客户端重新连接,他们来回发送更多信息,然后再次断开连接。
该过程的第一步工作正常。客户端连接,BeginAccept 根据需要触发,然后他们聊了一会儿。连接似乎关闭得很好(Disconnect()),逻辑运行并再次调用 BeginAccept。但是,如果客户端再次尝试连接,AcceptCallback 将不会触发。
网上其他问题/答案提示socket需要恢复,但我这里是这样做的。
在实际版本中(在此处进行了修剪)我有大量的异常处理和日志记录,但没有异常或错误可以使用。
如果我重新启动服务,它会再次运行(但只有一次),这让我相信这是我的服务器代码而不是我的客户端。 似乎 AsyncCallback 再也不会被触发了。
我做错了什么导致无法连接多次? 谢谢!
在服务器上,在一个线程中我有以下内容(这在开始时被调用,以及从客户端发送断开信号时):
try
{
//check connected, and if not connected, then close socket and reopen
if (mDisconnectFlag == true)
{
mDisconnectFlag = false;
this.Disconnect();
}
if (listener == null || listener.Connected == false)
{
// Create a TCP/IP socket.
this.listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
this.listener.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
// Bind the socket to the local endpoint and listen for incoming connections.
this.listener.Bind(localEndPoint);
this.listener.Listen(10);
// Start an asynchronous socket to listen for connections.
this.listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
}
else if (listener.Connected == false || mAcceptCallBackFlag == true)
{
// Start an asynchronous socket to listen for connections.
this.listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
}
// Wait until a connection is made before continuing.
_retevent = ProcessSocketEvent.WaitOne(mSocketProcessTimeInterval, false);
}
catch (Exception ex)
{
//logging - don't worry about this
}
断线如下:
public void Disconnect()
{
try
{
this.listener.Shutdown(SocketShutdown.Both);
this.listener.Disconnect(false);
this.listener.Dispose();
listener = null;
}
catch (Exception ex)
{
//logging
}
}
最后,回调:
public void AcceptCallback(IAsyncResult ar)
{
try
{
// Get the socket that handles the client request.
Socket listener = (Socket)ar.AsyncState;
Socket handler = listener.EndAccept(ar);
this.listener = handler;
// Create the state object.
StateObject state = new StateObject();
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReadCallback), state);
mAcceptCallBackFlag = true;
}
catch (Exception ex)
{
//logging
}
}
【问题讨论】: