网络关闭时TcpClient连接状态问题

时间:2014-09-29 13:18:20

标签: c# networking tcp tcpclient tcp-ip

我有一个TcpClient,我正在连接到机器,一切正常。现在还有一个额外的步骤,我想在定时器的帮助下,在60秒内监控连接状态。根据基础研究我已经知道没有直接的方法来测试它。所以我试图通过应用程序离开网络时发送到机器的最近消息的响应来获取它。

这是代码..

 // Find out whether the socket is connected to the remote host.

 //Send a message to Machine
 try
 {
  byte[] notify = Encoding.ASCII.GetBytes("Hello");
  stream.Write(notify, 0, notify.Length);     
 }catch { }

 //Check if it reached to machine or failed 
 bool getConnectionStatus = client.Connected;

 if (getConnectionStatus == true)
     {
         //Do nothing
     }
 else
     {
        //Stop the thread
        _shutdownEvent.WaitOne(0);
        _thread.Abort();

         //Start Again
         _thread = new Thread(DoWork);
         _thread.Start();
      }

但是,在这种情况下发生的最令人惊讶的事情是,如果机器不在网络中,那么在第一次写入时也能写入,这就是连接状态即将连接的原因,尽管它已经出来了第二次尝试发送数据时,它失败了,就像预期状态断开一样。

我面临的主要问题是,一旦它与网络断开连接,为什么它能够发送数据。因此,当网络熄灭时,我将丢失存储在机器中的所有缓冲区数据。 请帮帮我..

1 个答案:

答案 0 :(得分:1)

在幕后,Write操作只是将数据发送到网络层;在尝试传输数据之前,您可能会获得“成功”结果。如果数据很小,网络层甚至可以延迟发送数据一段时间,以试图一次发送一批几条消息。

Alex K.用几句话说,检查网络连接最可靠的方法是等待响应。如果在一定时间内未收到此类响应,则连接将丢失。

假设您继续使用“Hello”,服务器应该回答“是的!”。在客户端,您可以使用以下命令扩展当前代码:

try
{
    byte[] notify = Encoding.ASCII.GetBytes("Hello");
    stream.Write(notify, 0, notify.Length);
    byte[] notifyResult = new byte[5];
    int bytesRead = stream.Read(notifyResult, 0, 5);
    if (bytesRead == 0)
    {
        // No network error, but server has disconnected
    }

    // Arriving here, notifyResult should contain ASCII "Yeah!" 
}
catch (SocketException)
{
    // Network error
}

在服务器上,您应该识别正在发送的“Hello”,然后只需回答“是的!”。我不知道你的服务器当前做了什么,但它可以类似于:

switch (receivedMessage)
{
    case "Hello":
        stream.Write(Encoding.ASCII.GetBytes("Yeah!"), 0, 5);
        break;
}

请注意,您应该考虑将信息包装在信息包中,即:

<Message Type> <Message> <Terminator Character>
ie. "KHello\n"

<Size of Message> <Message Type> <Message> 
ie. "0005KHello" 

其中消息类型“K”是保持活动消息,新行“\ n”是终止符,“0005”是消息长度,不包括消息类型。

这样服务器将始终能够判断它是否收到了完整的消息,并且消息类型可以指示“Hello”是作为数据还是作为保持活动的数据包发送的。