if (socket != null && socket.Connected)
既然检查了socket.Connected属性,又何必加个 socket!=null ?
没有得到任何对象socket.Connected自然是false试试把发信息和接收信息分写在两个Timer中,要是能分别做到两个窗体里就更好了.
既然检查了socket.Connected属性,又何必加个 socket!=null ?
没有得到任何对象socket.Connected自然是false试试把发信息和接收信息分写在两个Timer中,要是能分别做到两个窗体里就更好了.
这个问题其实也很好的,不管是哪边断开都发送一条特殊的我们一般情况下不会输的指定,当对方收到的若是这样的指令,就表明已经断开了连接,自己也可以断开不需要再连接了
后来采用了比较原始的方法就是在心跳测试中调用ping命令去ping服务器,ping不通就报异常。
lz不妨试试
后来用了个土法解决的,就是在心跳代码中去ping,ping不通就报异常
{
if(socket.Available == 0) throw new Exception("网络断了");
}
这里的轮询间隔是以微秒(百万分之一秒)计算的,不用设得太小了
我把网线拔掉了,但是if (socket.Poll(100, SelectMode.SelectRead))总是为false不能执行进来
其他的情况需要借助Read/Send数据时捕捉错误码来判断了(在一个长连接中可以借助心跳包来处理)
byte[] inValue = new byte[] { 1, 0, 0, 0, 0x10, 0x27, 0, 0, 0xe8, 0x03, 0, 0 }; // True, 10秒, 1 秒
TcpSock.IOControl(keepAlive, inValue, null);
//Sock.IOControl(IOControlCode.KeepAliveValues, inValue, null);
//设置 KeepAlive 为 10 秒,检查间隔为 1 秒。如果拨掉客户端网线
//服务器的 Socket.Receive() 会在 10 秒后断开连接
Socket_e 是事件参数
外部对象获得SocketEvent事件进行重连操作即可
读的线程终止就可以了.
这只是一个类中的SOCKET读线程操作示例: //接收线程
public void Thread_Read()
{
while (true)
{
try
{ if (socket.Poll(-1, SelectMode.SelectRead))
{
byte[] bytes = new byte[socket.ReceiveBufferSize];
int bytesRec = socket.Receive(bytes);
string data = Encoding.UTF8.GetString(bytes, 5, bytesRec); Rec_e.vDataPack = data;
RecEvent(this, Rec_e);
if (bytesRec == 0)
{
//socket连接已断开
Socket_e.ResCode = "00000";
SocketEvent(this, Socket_e);
return;
}
}
else if (socket.Poll(-1, SelectMode.SelectError))
{
//TODO : SOCKET错误
}
}
catch (SocketException e)
{
//10035 == WSAEWOULDBLOCK
if (e.NativeErrorCode.Equals(10035))
{
//仍然处于连接状态,但是发送可能被阻塞
}
else
{
//连接错误,返回错误代码:e.NativeErrorCode
Socket_e.ResCode = e.NativeErrorCode.ToString();
SocketEvent(this, Socket_e);
return;
}
}
}
}
如果强制断开 那么在 另外一边会抛出异常
这个是我在http://technet.microsoft.com/zh-cn/system.net.sockets.socket.poll.aspx上看的,够权威吧,看来只能发一个特殊的东西给socket的另一方,再在对方的逻辑里写上收到的是这个特殊的东西就回发一个特殊的东西。这样才能保证socket还能用。而且还有。poll方法是向socket里写或者读出一部分数据,这样的话,如果你其他的线程也在接收socket里的数据的话,就会接收不全了,我在做一个远程通信软件时也遇到这样的问题。希望你能看到我这条回复,如果你已有好的解决办法,麻烦你给我留言,十分感谢!我也被这个问题困扰好久了。
超过一定时间没有收到ACK,就重发。
如果重发连续N次没收到ACK,就认为对方断开连接。
private void timer1_Tick(object sender, EventArgs e)
{
if (socket != null && socket.Connected)
{
if (socket.Poll(1, SelectMode.SelectRead))
{
try
{
byte[] temp = new byte[1024];
int nRead = socket.Receive(temp);
if (nRead == 0)
{
MessageBox.Show("000连接已断开了,请处理");
}
}
catch
{
MessageBox.Show("连接已断开了,请处理");
}
}
try
{
int ii=socket.Send(new byte[1]);
}
catch (SocketException se)
{
if (se.ErrorCode == 10054) // Error code for Connection reset
{ MessageBox.Show("连接已断开了,请处理");
}
else
{
MessageBox.Show(se.Message);
}
} }
}