socket服务器断开后的异常处理(转)
1.服务器强制断开导致客户端断开
办法一:捕获接到的数据,如果是0,判断服务器已经断开,关闭socket,进行重新连接。
办法二:SOCKET一直就有这个问题,服务端断开以后,相信你的客户端的CPU一直处于100%,因为再不停的无限循环的接受一个0字节包
解决办法就是发送心跳包,或者每收到一个包,就发送一个0字节包,断开了的话就会异常。
其实主要的问题是服务端如果是强制断开,也就是物理断开或者直接结束了进程这种断开,客户端是接收不到断开请求的,也就是说这个时候的客户端并不认为断开了,而且客户端还在不停的接受一个0字节的数据包,无限循环,所以还会导致客户端的CPU一直处于100%的状态
这个问题我之前写一个C/S通讯程序的时候碰到过,解决办法找了一天都是些非常麻烦的方案,于是我自己想了个办法,就是在每次接受数据的时候,发送一个0
字节包,这样的话服务端如果断开,那么客户端就会开始无限循环接受一个0字节包,那么再接受以后,按我说的方案,还会在返回一个0字节包,但是肯定无法发
送,所以会异常,扑获就OK了!!
客户端代码:
'接受数据,收到后返回一个垃圾包
XXX.Send(Encoding.Unicode.GetBytes("0")) '垃圾包
'如果服务端已断开,那么肯定发不出去,结果异常,扑获就行了。
办法三:可能是你的 客户端 没有 收到断开连接的 信息。 这个需要在通信 协议里面 加个 心跳 报文, 每隔多少时间 收不到 就 断开 重连。
2.客户端第一次没有连接成功,重新连接/中途断开,隔一段时间自动重连。
办法一:如果第一次就没有连接成功,捕获异常进行重新连接即可。
办法二:如果中途,被远程主机强制断开,可增加一个计时器,判断socket状态,如果不是连接状态,隔一段时间自动重连。
简单例子代码:
public class MySocket
{
Socket m_socket = null;
public string server_ip;
public int server_port;
public Socket createClientSocket()
{
//在这里利用上面的IP和PORT建立到服务器的连接。
//成功返回对应的Socket
//失败则返回null;
}
public bool connect()
{
//在这里调用上面的连接方法
m_socket = null;
m_socket =createClientSocket();
if(m_socket == null)
{
return false;
}
return true;
}
publice bool reconnect()
{
//还和上面一样调那个方法
}
///专门用来发送数据的方法
publice int sendData()
{
//在这里,发送数据前就要调用下面的函数检查Socket的状态
bool ret = true;
bool isConnected = false;
bool isRead = false;
bool isWrite = false;
bool isError = false;
int avalSize =0;
ret =checkSocket(ref isConnected,ref isRead,ref isWrite,ref isError,ref avalSize);
if( ret = false
|| isConnected == false
|| isErr == true
|| (isRead == true && AvailableSize == 0
)
{
//这里就调用那个重联的
reconnect();
}
//完毕后再检查一遍,看这次连上了没
ret =checkSocket(ref isConnected,ref isRead,ref isWrite,ref isError,ref avalSize);
if( ret = false
||