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

本文关键字:连接 状态 问题 TcpClient 网络 | 更新日期: 2023-09-27 18:25:00

我有一个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();
      }

但在这种情况下发生的最令人惊讶的事情是,如果机器不在网络中,那么在第一次写入时,它也能够写入,这就是为什么连接状态显示为已连接,尽管它在网络之外。第二次,当它试图发送数据时,它失败了,类似于预期的状态是断开连接。

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

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

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

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

假设您一直使用"Hello",服务器应该以"Yes!"作为响应。在客户端,您可以使用以下代码扩展当前代码:

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",并简单地回复"Yes!"。我不知道你的服务器目前做什么,但它可能类似于:

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"是作为数据还是作为保活数据包发送的。