2009-09-09 83 views
0

我试图找出一个Socket目前是否已连接 - 根据MSDN文档为Socket.Connected - 我应该做到以下几点:确定.NET套接字当前是否连接了错误?

// This is how you can determine whether a socket is still connected. 
bool blockingState = client.Blocking; 
try 
{ 
    byte [] tmp = new byte[1]; 

    client.Blocking = false; 
    client.Send(tmp, 0, 0); 
    Console.WriteLine("Connected!"); 
} 
catch (SocketException e) 
{ 
    // 10035 == WSAEWOULDBLOCK 
    if (e.NativeErrorCode.Equals(10035)) 
     Console.WriteLine("Still Connected, but the Send would block"); 
    else 
    { 
     Console.WriteLine("Disconnected: error code {0}!", e.NativeErrorCode); 
    } 
} 
finally 
{ 
    client.Blocking = blockingState; 
} 

Console.WriteLine("Connected: {0}", client.Connected); 

我测试过这个工程通过套接字连接到远程服务器在Windows上运行并杀死远程服务器,它工作正常。但是,如果我对在Unix上运行的远程服务器(在这种情况下是MAC OS X)执行相同的操作,则代码不起作用 - client.Send(tmp, 0, 0)调用完成而不会抛出异常并打印“Connected:true”。

我猜这与事实有关,连接的另一端已关闭,所以发送仍然可以工作,但接收会失败 - 我可以做一个零字节接收或东西,看看是否套接字是关闭的?

回答

2

是的,你可以。

调用只发送真正检查本地套接字是否打开。呼叫接收也会检查另一端。

+0

当我在远程对象断开连接后使用Receive时,它也成功完成,但返回0 - 这是检测连接丢失的可靠方法吗? – Nosrama 2009-09-09 10:03:08

+1

不幸的是,没有真正的单一故障安全方法来检测连接是否还活着,但实际上并未尝试使用连接并捕获任何错误/异常。将套接字连接封装到带有接收缓冲区的类中是非常标准的,这样您就可以从线路中读取实际数据,以便在有人真正想要使用它时测试连接并将其存储起来。同样如Oliver所述,TCP堆栈的各种实现之间存在差异,这意味着您将从不同的同行获得不同的行为。 – 2009-09-09 11:47:34

1

也许你可以用Wireshark来嗅探流量,看看垂死的服务器端是windows还是unix系统是否有区别。

也许临死的windows系统能够发送一个tcp关闭,而unix系统不能。这将解释差异(但也许不会帮助你的实际问题)。

顺便说一句,如果你会使用udp连接,你永远无法确定如果其他网站是活着的,由于事实上这将是一个发送&忘记通信。