我正在创建一个客户端服务器应用程序。服务器已经设计好并等待客户端的连接。现在在客户端部分,我希望在应用程序的整个生命周期中保持连接活动,并且只有在主客户端应用程序关闭或关闭或服务器关闭时才会关闭连接。
目前每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) */
}
}
}
答案 0 :(得分:6)
在致电SetSocketOption()
时,KeepAlive
在SocketOptionLevel.Tcp
级别无效,而是使用SocketOptionLevel.Socket
。
SetSocketOption( SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true )
;
答案 1 :(得分:2)
上面的评论和回答是有效的 - 听起来像是一个糟糕的设计选择,在应用程序的整个生命周期中打开一个套接字并期望事情正常工作 - 你应该建立某种故障保护机制,以防连接被丢弃
回到保持活动:你需要它们两端 - 服务器和客户端,所以检查两侧的套接字是如何设置的。我认为保持活动的默认值是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
答案 2 :(得分:1)
代码中的注释(“没有datapacket意味着没有TCP连接”)放在从另一端收到断开连接(0字节)数据包的位置。没有办法让 连接保持活动状态,因为另一方选择来关闭它。
如果由于网络问题而关闭连接,您将获得异常,或者看起来连接有效但安静。
保持活动机制始终与超时一起工作 - 超时强制执行“如果没有收到x秒的数据,关闭连接”,其中keep-alive只发送一个虚拟数据包以防止发生超时。
通过自己实现协议(您在TCP / IP级别上运行),如果已经在另一端实施了超时,则只需要实现keep-alive。
答案 3 :(得分:1)
您可以通过在服务器上创建套接字时设置IOControlCode.KeepAliveValues来设置TCP keepAlives。以下关于代码项目的文章很好地解释了它。