5

我正在创建一个客户端服务器应用程序。服务器已经设计好并等待来自客户端的连接。现在在客户端部分,我想在应用程序的整个生命周期中保持连接活动,并且连接仅在主客户端应用程序关闭或关闭或服务器关闭它时关闭。

目前每 10 秒服务器关闭 TCP 连接。我尝试使用

socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.KeepAlive, true);

但这对我不起作用..下面是我的代码块

public TCPStreamDevice(string RemoteIPAddress, int RemotePort, string SourceIPAddress, int SourcePortNo)        
{
    mIpAddress = RemoteIPAddress;
    mPort = RemotePort;

    mClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    System.Net.IPEndPoint LocalEndPoint = new System.Net.IPEndPoint(System.Net.IPAddress.Parse(SourceIPAddress), SourcePortNo);

    mClient.Bind(LocalEndPoint);

    mDataReceivedCallback = new AsyncCallback(DataReceivedTCPCallback_Handler);
    mBuffer = new byte[1024];
    Description = new DeviceDescription();
}

在处理程序中我有:

private void DataReceivedTCPCallback_Handler(IAsyncResult ar)
{
    try
    {
        Socket client = (Socket)ar.AsyncState;
        int bytesReceived = client.EndReceive(ar);

        if (bytesReceived > 0)
        {
            //to know transport level errors
            //EngineInterface.reponseReceived(mBuffer, false);

            ReceiveCallBackFunc(mBuffer, bytesReceived);

            client.BeginReceive(mBuffer, 0, 1024, SocketFlags.None, DataReceivedTCPCallback_Handler, client);
        }
        else
        {
            //disconnect
            /* when there is no datapacket  means no TCP connection is alive now (how can i keep Tcp alive here) */
        }
    }
}
4

3 回答 3

9

在对 的调用中SetSocketOption()KeepAlive在级别上无效SocketOptionLevel.Tcp,而是使用SocketOptionLevel.Socket.

SetSocketOption( SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true );

于 2016-05-05T13:58:53.077 回答
2

上面的评论和答案是有效的——听起来像是一个糟糕的设计选择,在应用程序的整个生命周期都打开了一个套接字,并期望事情能够正常工作——你应该建立某种故障保护机制,以防连接断开。

回到keep-alives:你在两端都需要它们——服务器和客户端,所以检查两端的套接字是如何设置的。我认为保持活动的默认值为 2 小时 - 等待保持活动数据包的时间很长,但可以更改。检查Socket.IOControl方法并使用IOControlCode.KeepAliveValues看起来像这样的结构(非托管)http://msdn.microsoft.com/en-us/library/ms741621.aspx。更多关于这里的控制代码:http: //msdn.microsoft.com/en-us/library/system.net.sockets.iocontrolcode.aspx

于 2013-08-28T14:38:05.810 回答
1

代码中的注释(“没有数据包意味着没有 TCP 连接”)放置在从另一端接收断开连接(0 字节)数据包的位置。由于对方选择关闭它,因此无法保持该连接处于活动状态

如果连接由于网络问题而被关闭,您会得到一个异常,或者看起来连接有效但安静。

Keep-alive 机制总是与超时一起工作——超时强制“如果在 x 秒内没有收到数据,则关闭连接”,其中 keep-alive 只是发送一个虚拟数据包以防止超时发生。

通过自己实现一个协议(您在 TCP/IP 级别上运行),如果您已经在另一端实现了超时,您只需要实现一个 keep-alive。

于 2013-08-28T13:58:15.370 回答