【问题标题】:TcpClient connection status issue on Network DownNetwork Down 上的 TcpClient 连接状态问题
【发布时间】:2014-09-29 13:18:19
【问题描述】:

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

但在这种情况下发生的最令人惊讶的事情是,如果机器不在网络中,那么在第一次写入时它也能够写入,这就是为什么连接状态虽然已经断开但仍然显示为已连接网络。第二次尝试发送数据时失败,并且预期状态已断开。

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

【问题讨论】:

  • 发送“PING”,等待“PONG”
  • @AlexK。对不起,我没有得到你

标签: c# networking tcp tcpclient tcp-ip


【解决方案1】:

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

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

假设您继续使用“Hello”,服务器应该响应“Yeah!”。在客户端,你可以扩展你当前的代码:

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

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”是 Keep-alive 消息,换行符“\n”是终止符,“0005”是不包括消息类型的消息长度。

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

【讨论】:

  • 您能否在帖子中给我示例或与我的代码的伪代码连接。实际上我是该领域的新手,所以没有清楚地了解条款
  • @shubhamHegdey 添加了一个示例。我希望你能在这方面取得一些进展。
猜你喜欢
  • 1970-01-01
  • 2014-10-06
  • 1970-01-01
  • 2015-03-27
  • 1970-01-01
  • 1970-01-01
  • 2013-09-03
  • 2022-12-17
  • 2016-04-08
相关资源
最近更新 更多