断开连接后,C#Client / Server套接字将不再连接

时间:2017-09-26 21:57:30

标签: c# sockets

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

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

这个过程的第一步很好。客户端连接,BeginAccept根据需要触发,然后他们聊了一会儿。连接似乎正常关闭(Disconnect()),逻辑运行并再次调用BeginAccept。但是,如果客户端再次尝试连接,则不会触发AcceptCallback。

在线的其他问题/答案表明套接字需要恢复,但我这样做。

在真实版本中(此处已修剪)我有广泛的异常处理和日志记录,但没有例外或错误可供使用。

如果我重新启动服务,它会再次运行(但只有一次),这让我相信它是我的服务器代码,而不是我的客户端。 似乎AsyncCallback根本不会再被触发。

我做错了什么,以至于我无法连接多次? 谢谢!

在服务器上,在一个线程中,我有以下内容(这在开始时调用,以及从客户端发送断开连接信号时):

onPrepare: function () {
    'use strict';
    browser.waitForAngularEnabled(false);
}

断开连接如下:

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
    }

}

1 个答案:

答案 0 :(得分:0)

问题是你再也不会打电话给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。