求教高手怎样获取Socket的连接状态? 这个if(!skSocket.Connected)语句根本没起到作用。 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 最近看到好多这样的问题,我不知道是不是因为这个Connected属性无法实时地监控连接状态的原因。根据TCP的原理,似乎通讯一方如果不进行接收或发送数据的操作是无法得知另一方是否断开连接的。临时解决办法你可以另开一条连接来定时在双方发送在线信息,这样就可以监测到 Socket编程不熟悉,不知道下面的解决方法是否可行,仅供参考。通讯的时候在服务器上注册客户端,在指定的时间(定时器),由服务器发送消息到客户端判断客户端是否存在(轮询),对于不存在的客户端服务器自动将其注销。其实只要你在该链路上实现一个简单的消息订阅机制就可以了。具体实现细节希望你可以自己完成! 通常可以这样:private void OnPacketReceived(IAsyncResult ar) { int receivedBytes = 0; try { receivedBytes = m_socket.EndReceive(ar); if ((receivedBytes == 0)||(ReceptionPacket == null)) { OnConnectionFail((byte)ConnectionReason.NullPacket); return; } } catch { OnConnectionFail((byte)ConnectionReason.ClosedConnection); return; } while(true) { data = new byte[1024]; recv = client.Receive(data);//阻塞,返回接收到的字节数,当检测到客户机关闭会话,发送TCP FIN包时,就返回0 if(recv == 0) break; string msg = Encoding.ASCII.GetString(data,0,recv); listBox1.Items.Add("来自客户端消息:" + msg); client.Send(data,recv,SocketFlags.None); } IPHostEntry iphe =Dns.Resolve(clientep.Address.ToString()); listBox1.Items.Add("已经从" + clientep.Address + "(" + iphe.HostName + ")" +" 断开连接"); client.Close(); newsock.Close(); 下面是Clientwhile(true) { data = new byte[1024]; recv = client.Receive(data);//阻塞,返回接收到的字节数,当检测到客户机关闭会话,发送TCP FIN包时,就返回0 if(recv == 0) break; string msg = Encoding.ASCII.GetString(data,0,recv); listBox1.Items.Add("来自客户端消息:" + msg); client.Send(data,recv,SocketFlags.None); } IPHostEntry iphe =Dns.Resolve(clientep.Address.ToString()); listBox1.Items.Add("已经从" + clientep.Address + "(" + iphe.HostName + ")" +" 断开连接"); client.Close(); newsock.Close(); } skSocket = tlListen1.AcceptSocket ( ) ; //接受远程计算机的连接请求,并获得用以接收数据的Socket实例 skSocket.Connect(YOURIP); 这个是SERVERwhile(true) { time++; input = temp; if(time == 6) break; server.Send(Encoding.ASCII.GetBytes(input)); data = new byte[1024]; recv = server.Receive(data); stringData = Encoding.ASCII.GetString(data,0,recv); listBox1.Items.Add("来自服务器信息:" + stringData); } IPEndPoint serverep = (IPEndPoint)server.RemoteEndPoint; listBox1.Items.Add("从务器:" + serverep.Address +":" + serverep.Port + " 断开"); server.Shutdown(SocketShutdown.Both); server.Close(); 1979xt(VS.NET为未来十年作好了准备,你呢) 说的应该是正确的。当SOCKET正在接收数据时,如果对方突然当机或其它原因,造成失去连接时,你会收到一个异常的。我给出的那段代码就是基于这原理。 HNU(嶽麓書院,為楚有材,於我為盛!) 说的这个还是基于cs模型的,我这个是想实现p2p,从而不存在cs结构,因为当对方断开连接后,我无法进行调试,但是根据判断其while ( listenerRun ) { if(!skSocket.Connected){statusBar1.Panels[0].Text = "'" + HostName +"' " + "远程计算机关闭连接!" ;statusBar1.Panels[1].Text = "断开与"+"'" + HostName +"' " + "远程计算机的连接!" ; listenerRun = false ; break;}else{Byte[] stream = new Byte[80] ; //定义从远程计算机接收到数据存放的数据缓冲区 string time = DateTime.Now.ToString ( ) ; //获得当前的时间 int i = skSocket.ReceiveFrom ( stream,ref tempRemoteEP ) ; //接收数据,并存放到定义的缓冲区中 string sMessage = System.Text.Encoding.UTF8.GetString ( stream ) ; //以指定的编码,从缓冲区中解析出内容 listBox2.Items.Add(time+""+HostName+":"); listBox2.Items.Add ( sMessage ) ; //显示接收到的数据 } } }代码中listenerRun 值依旧为true,所以本机不停收到远程机发的空消息,我想能不能通过使用skSocket.Shutdown(SocketShutdown.Both); skSocket.Close();关闭socket使其skSocket.Connected为false。 我用TCP做聊天工具的时候是用这样的土办法:当一方断开连接前,先向对方发送一条标识退出的信息,对方收到这个消息就关掉Socket 首先,你可以看一下“三方握手”的概念,再来写这些网络程序,搞不清最基本的原理,就会给以后的编程带来很多麻烦。“蓝军白军”的故事已经讲得很清楚,TCP连接是无法得知最后一个消息是否到达对方的,但是在TCP/IP协议中,它默认经过三次握手就建立了连接,所以P2P在建立连接之后,如果有一方单方面断开了连接,对方是不会马上知道的。那么怎么才能获取这个连接已经中断了呢?1、如果这个中断是预定的话,也就是说某一方要中断,可以先通知一下对方的话,就可以用 kalewa(山歌) 的办法来实现,中断之前告诉对方“我要断了,你可以关闭连接了”。2、如果这个中断是突发或者偶然的话,那么我怎么知道对方断掉这个连接了呢?先看看楼上的回答://////////////////////////“haiwangstar(南河三(天狼星上有没有普及C#)) ”当SOCKET正在接收数据时,如果对方突然当机或其它原因,造成失去连接时,你会收到一个异常的。我给出的那段代码就是基于这原理。这个说法并没有错,但是它并不能解决你的问题,因为楼上的说法是有前提的——“当SOCKET正在接收数据时”,如果这个时候Socket空闲,这个异常你就捕获不到了。那么有没有解决方案呢?方案一:你可以每隔20秒或者一个间隔时间向对方发送一个确认信息,告诉对方你还在,然后彼此进行这个过程,让程序知道整个过程还在继续。方案二:你可以写一个 像Sniffit这样的程序,来监测对方的TCP Packet,这个程序就负责即时的通知你的主程序,对方的TCP Packet还是发过来了,他还在。至于如何写这个Sniffit程序,还是先劝劝你看看Raw Socket原理和ICMP协议格式,这些对你进行以后的学习和应用都是很有帮助的。 如何让PDF文件不让下载,只可浏览 在VSwinfrom中如何画如下图的效果? C#实现远程关机功能(windows和linux)源码实例 datagridview的数据传递!! 目前公司里开发有关asp.net技术有哪些 关于input的问题!!! 怎样 根据特定时间 访问服务器? 【在线等。。。。】 对数据库中的数据进行查询并将结果显示在dataGrid中 在c#中如何教用C++的动态库的问题 大家看看哪里错了,我用的是旧版的教材. 参数保存问题 如何判断MMS:// 连接的文件?顶帖有分!
通讯的时候在服务器上注册客户端,在指定的时间(定时器),由服务器发送消息到客户端判断客户端是否存在(轮询),对于不存在的客户端服务器自动将其注销。其实只要你在该链路上实现一个简单的消息订阅机制就可以了。具体实现细节希望你可以自己完成!
{
int receivedBytes = 0;
try
{
receivedBytes = m_socket.EndReceive(ar);
if ((receivedBytes == 0)||(ReceptionPacket == null))
{
OnConnectionFail((byte)ConnectionReason.NullPacket);
return;
}
}
catch
{
OnConnectionFail((byte)ConnectionReason.ClosedConnection);
return;
}
while(true)
{
data = new byte[1024]; recv = client.Receive(data);//阻塞,返回接收到的字节数,当检测到客户机关闭会话,发送TCP FIN包时,就返回0 if(recv == 0)
break; string msg = Encoding.ASCII.GetString(data,0,recv); listBox1.Items.Add("来自客户端消息:" + msg); client.Send(data,recv,SocketFlags.None); } IPHostEntry iphe =Dns.Resolve(clientep.Address.ToString()); listBox1.Items.Add("已经从" + clientep.Address + "(" + iphe.HostName + ")" +" 断开连接"); client.Close(); newsock.Close();
下面是Clientwhile(true)
{
data = new byte[1024]; recv = client.Receive(data);//阻塞,返回接收到的字节数,当检测到客户机关闭会话,发送TCP FIN包时,就返回0 if(recv == 0)
break; string msg = Encoding.ASCII.GetString(data,0,recv); listBox1.Items.Add("来自客户端消息:" + msg); client.Send(data,recv,SocketFlags.None); } IPHostEntry iphe =Dns.Resolve(clientep.Address.ToString()); listBox1.Items.Add("已经从" + clientep.Address + "(" + iphe.HostName + ")" +" 断开连接"); client.Close(); newsock.Close();
}
//接受远程计算机的连接请求,并获得用以接收数据的Socket实例 skSocket.Connect(YOURIP);
这个是SERVERwhile(true)
{
time++;
input = temp; if(time == 6)
break; server.Send(Encoding.ASCII.GetBytes(input)); data = new byte[1024]; recv = server.Receive(data); stringData = Encoding.ASCII.GetString(data,0,recv); listBox1.Items.Add("来自服务器信息:" + stringData);
}
IPEndPoint serverep = (IPEndPoint)server.RemoteEndPoint; listBox1.Items.Add("从务器:" + serverep.Address +":" + serverep.Port + " 断开"); server.Shutdown(SocketShutdown.Both); server.Close();
while ( listenerRun )
{
if(!skSocket.Connected)
{
statusBar1.Panels[0].Text = "'" + HostName +"' " + "远程计算机关闭连接!" ;
statusBar1.Panels[1].Text = "断开与"+"'" + HostName +"' " + "远程计算机的连接!" ;
listenerRun = false ;
break;
}
else
{
Byte[] stream = new Byte[80] ; //定义从远程计算机接收到数据存放的数据缓冲区
string time = DateTime.Now.ToString ( ) ; //获得当前的时间
int i = skSocket.ReceiveFrom ( stream,ref tempRemoteEP ) ; //接收数据,并存放到定义的缓冲区中
string sMessage = System.Text.Encoding.UTF8.GetString ( stream ) ; //以指定的编码,从缓冲区中解析出内容
listBox2.Items.Add(time+""+HostName+":");
listBox2.Items.Add ( sMessage ) ; //显示接收到的数据
}
}
}
代码中listenerRun 值依旧为true,所以本机不停收到远程机发的空消息,我想能不能通过使用skSocket.Shutdown(SocketShutdown.Both); skSocket.Close();关闭socket使其skSocket.Connected为false。
先看看楼上的回答:
//////////////////////////
“haiwangstar(南河三(天狼星上有没有普及C#)) ”
当SOCKET正在接收数据时,如果对方突然当机或其它原因,造成失去连接时,你会收到一个异常的。我给出的那段代码就是基于这原理。这个说法并没有错,但是它并不能解决你的问题,因为楼上的说法是有前提的——“当SOCKET正在接收数据时”,如果这个时候Socket空闲,这个异常你就捕获不到了。那么有没有解决方案呢?
方案一:你可以每隔20秒或者一个间隔时间向对方发送一个确认信息,告诉对方你还在,然后彼此进行这个过程,让程序知道整个过程还在继续。方案二:你可以写一个 像Sniffit这样的程序,来监测对方的TCP Packet,这个程序就负责即时的通知你的主程序,对方的TCP Packet还是发过来了,他还在。至于如何写这个Sniffit程序,还是先劝劝你看看Raw Socket原理和ICMP协议格式,这些对你进行以后的学习和应用都是很有帮助的。