Linux中TCP通信中 send函数 如何判断 何时断开连接了

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux中TCP通信中 send函数 如何判断 何时断开连接了相关的知识,希望对你有一定的参考价值。

参考技术A 1 确认链路是否连通状态,最好加心跳机制, 如果一定时间没有收到心跳包,或者没有回复心跳
就应认为此链路已经坏掉了,需要关闭,重新连接!

2 至于发送数据,应该检查对应的api的返回值,是否已经成功发送或者接受定长数据!
没有完成应该重新发送或者接受

3 网络数据问题,可以用抓包工具直接抓包看数据,可以看的比较透彻
工具 Linux下用tcpdump,windows用wirekshark本回答被提问者采纳

避免重新组装的TCP段“Modbus TCP通信”

我在FHPP模式下与FESTO控制器进行通信,正如我在之前的问题Qt/C++ communication with CMMO-ST-C5-1-LKP Festo controller over Modbus TCP中提到的那样,我正在尝试详细说明一个连续的Modbus TCP通信。我创建了一个函数Send_data(),允许发送一个Modbus TCP数据包,使其成为一个连续的通信,我使用全局QTimer,并使它每100毫秒触发一次这个函数:

m_timer->start(100) connect(m_timer, &QTimer::timeout, [this]() { Send_Data(); });

当配置位固定为0或1时没有问题,然后我可以更改我的全局变量QString Data数据包,它将发送它。问题是必须将位(配置或定位)作为上升沿或下降沿触发。当我尝试这样做时,这会创建重新组装的TCP段(如下图所示):

void Stepper::trigger_bit(bit bitName){
switch (bitName) {
case(RES): {    
    activer_reset();break;
}
case(HOM): {
    activer_homing();
    break;
}
case(START): {
    activer_start();
    break;
}
case(CLEAR): {
    activer_clear();
    break;
}
case(HALT): {
    desactiver_halt();
    break;
}
}
connect(m_timer, &QTimer::timeout, [this]() {
    Send_Data();
});
switch (bitName) {
    case(RES): {
    desactiver_reset();break;
}
case(HOM): {
    desactiver_homing();
    break;
}
case(START): {
    desactiver_start();
    break;
}
case(CLEAR): {
    desactiver_clear();
    break;
}
case(HALT): {
    activer_halt();
    break;
}
}
connect(m_timer, &QTimer::timeout, [this]() {
    Send_Data();
});} 

trigger_bit(bit bitName)中的这些方法修改了QString Data变量中的位。)

enter image description here

在我尝试第二次移动电机的阶段,我需要重新触发START位,我这样做但是它没有被触发,并且命令不会由电机执行。我假设重新组装的TCP段是问题所在,因为每次按下移动按钮(我触发具有不同位置的START位),一个或多个TCP段被添加到发送的数据包中。通常情况下,这意味着Send_Data()函数会一直触发它的旧调用但总是触发新的QString Data。有没有解决方案来避免这个问题?比如在Send_Data()函数上创建互斥变量。

答案

我并不完全理解您的问题,但我想澄清一点,TCP并不保证发送的数据包在另一端以与发送数据包相同的块接收。

可能会发送100 + 100个字节,另一端将接收200字节的块,或者接收150个中的一个和50个中的另一个。没有办法防止这种情况发生,TCP以这种方式工作

接收程序必须准备好重新组合片段。

以上是关于Linux中TCP通信中 send函数 如何判断 何时断开连接了的主要内容,如果未能解决你的问题,请参考以下文章

当 TCP 连接中的链接断开时的 send() 函数行为

Java中使用Socket连接判断Inputstream结束,java tcp socket服务端,python tcp socket客户端

深入理解TCP协议及其源代码-send和recv背后数据的收发过程

避免重新组装的TCP段“Modbus TCP通信”

Linux深入理解TCP协议(connectbindlistenaccept)及其源码

linux中read,write和recv,send的区别