我正在構建一個基於服務器和基於客戶端的應用程序,它通過套接字(典型的東西)進行通信。C#客戶端/服務器套接字在斷開連接後將不會再次連接
預期的功能是客戶端連接,它們來回發送一些數據,然後客戶端關閉連接。一段時間後,客戶端重新連接,他們來回發送更多信息,並再次斷開連接。
該過程的第一步正常工作。客戶端連接,BeginAccept根據需要熄滅,並且他們聊了一會兒。連接似乎關閉就好(Disconnect()),邏輯運行並再次調用BeginAccept。但是,如果客戶端嘗試再次連接,AcceptCallback將不會觸發。
在線其他問題/答案建議套接字需要恢復,但我這樣做。
在真實版本(這裏修剪)我有廣泛的異常處理和日誌記錄,但沒有任何例外或錯誤的工作。
如果我重新啓動服務,它將再次運行(但只有一次),這導致我相信這是我的服務器代碼,而不是我的客戶端。 看來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
}
}
感謝您提供有關BeginAccept()的信息。我給出的第一個代碼片段是循環運行的。所以我再次調用BeginAccept()。但是,我應用了您的第一個建議並停止了循環,並且它可以正常工作。 – Jonathan