gpt4 book ai didi

c# - 断开连接后,C#客户端/服务器套接字将无法再次连接

转载 作者:行者123 更新时间:2023-12-03 11:55:07 25 4
gpt4 key购买 nike

我正在构建一个通过套接字(典型的东西)进行通信的基于服务器和客户端的应用程序。

预期的功能是客户端连接,它们来回发送一些数据,然后客户端关闭连接。一段时间后,客户端重新连接,他们来回发送更多信息,然后再次断开连接。

该过程的第一步运行良好。客户端连接,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()了。确实,您在建立第一个连接后就立即丢弃了原始的监听套接字。
关于如何编写基于套接字的网络代码,有很多正确的示例,因此,我不会赘述。特别是,由于这里没有好的Minimal, Complete, and Verifiable code example可供使用。但是,在您发布的代码中,似乎需要进行的主要更改是替换:

   this.listener = handler;
和:
   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);

}
而且没有什么可以设置您在此处等待的 ProcessSocketEvent的:
_retevent = ProcessSocketEvent.WaitOne(mSocketProcessTimeInterval, false);
如果这不是您已省略的代码部分,则应摆脱 WaitOne()调用,或确保已设置事件句柄。同样,尚不清楚该代码的目的是什么。如果您处在希望再次调用 BeginAccept()的循环中,则说明您混合了各种示例(不幸的结果是,当人们遵循MSDN套接字示例时,有时会发生这种情况,这是可怕的)。如果要在循环中进行阻止和接受,只需使用同步 Accept()方法。如果要使用 BeginAccept(),则不需要循环。只需在完成回调方法中调用 BeginAccept()之后再调用 EndAccept()即可。
如果您需要更多帮助,请改善问题,并确保有一个良好的MCVE。

关于c# - 断开连接后,C#客户端/服务器套接字将无法再次连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46436459/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com