C# Tcp连接保持活动

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18488562/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 12:22:22  来源:igfitidea点击:

Tcp connection Keep alive

c#tcp

提问by Balwinder SIngh

i am creating a client server application. the server is already design and in place waiting for connection from the client. Now in the client section i would like to keep the connection alive throughout th life of the application and the connection only closes when the main client application close's or shutdown or the server closes it.

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

Currently every 10 seconds Server closes the TCP connection.I tried with

目前每 10 秒服务器关闭一次 TCP 连接。我试过

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

but it doesn't work for me.. Below is my code block

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

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();
}

and in the handler I have:

在处理程序中,我有:

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) */
        }
    }
}

回答by C.Evenhuis

The comment ("whrn there is no datapacket means no TCP connection") in your code is placed where you receive a disconnect (0 bytes) packet from the other side. There is no way to keep thatconnection alive because the other side chosesto close it.

代码中的注释(“whrn there is no datapacket mean no TCP connection”)位于您从另一端接收到断开连接(0 字节)数据包的位置。没有办法保持连接处于活动状态,因为另一方选择关闭它。

If the connection is being closed due to network issues, you would either get an exception, or it would seem as if the connection is valid but quiet.

如果连接因网络问题而被关闭,您要么会收到异常信息,要么看起来好像连接有效但很安静。

Keep-alive mechanisms always work alongside with timeouts - the timeout enforces "if no data was received for x seconds, close the connection" where the keep-alive simply sends a dummy data packet to keep the timeout from occurring.

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

By implementing a protocol yourself (you're operating on the TCP/IP level) you only need to implement a keep-alive if you already have a timeout implemented on the other side.

通过自己实现协议(您在 TCP/IP 级别上操作),如果您已经在另一端实现了超时,则只需要实现保持活动。

回答by bkdc

The comments and answer above are valid - sounds like a bad design choice to have a socket opened for the entire lifetime of the app AND expect things to work properly - you should build some sort of failsafe mechanism in case the connection gets dropped.

上面的评论和答案是有效的 - 在应用程序的整个生命周期内打开一个套接字并期望一切正常工作,这听起来像是一个糟糕的设计选择 - 您应该构建某种故障安全机制,以防连接断开。

Back to keep-alives: You need them on both ends - server and client so check how the sockets are set up on both sides. I think that the default value for keep alives is 2 hours - that's a long time to wait for a keep-alive packet but it can be changed. Check Socket.IOControlmethod and use IOControlCode.KeepAliveValueswith a structure that looks like this (unmanaged) http://msdn.microsoft.com/en-us/library/ms741621.aspx. More about control codes here: http://msdn.microsoft.com/en-us/library/system.net.sockets.iocontrolcode.aspx

回到 keep-alives:你在两端都需要它们——服务器和客户端,所以检查两端的套接字是如何设置的。我认为keep alives 的默认值是2 小时——等待keep-alive 数据包的时间很长,但可以更改。检查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

回答by user797717

You can set TCP keepAlives by setting the IOControlCode.KeepAliveValues when creating the socket on the server. The article below on code-project explains it very well.

您可以通过在服务器上创建套接字时设置 IOControlCode.KeepAliveValues 来设置 TCP keepAlives。下面关于代码项目的文章很好地解释了它。

Sample on How-To set keep alive values

关于如何设置保持活动值的示例

回答by Alan

In the call to SetSocketOption(), KeepAliveis not valid at the SocketOptionLevel.Tcplevel, instead use SocketOptionLevel.Socket.

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

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

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