【问题标题】:Why does socket send() return successful code in case of cable connection was broken?为什么在电缆连接断开的情况下套接字发送()返回成功代码?
【发布时间】:2020-03-02 10:29:53
【问题描述】:

我通过 TCP 套接字连续发送数据包。然后,我拔掉网线,发现 send() 仍然返回成功。为什么? 启动代码如下:

// This function must be called before any other functions called.
/*  Return:
        0: success
        1: init socket fail
        2: send fail
        3: connect fail
*/

int mtMqttInit (const char *id, const char *username, const char *password, const char *hostName, const int tcpPort, unsigned int timeoutSec)
{
    int pktLen;

    mqtt_init(&mtBroker, id);
    mqtt_init_auth(&mtBroker, username, password);

    if (init_socket(&mtBroker, hostName, tcpPort)) {
        if (debug)
            printf ("init_socket()\n");
        return MT_MQTT_INIT_SOCKET_FAIL;
    }

    if (mqtt_connect(&mtBroker) == -1) {
        if (debug)
            printf ("mqtt_connect()\n");
        return MT_MQTT_INIT_CONNECT_FAIL;
    }
    .....
}

void mqtt_init(mqtt_broker_handle_t* broker, const char* clientid) {
    // Connection options
    broker->alive = 300; // 300 seconds = 5 minutes
    broker->seq = 1; // Sequency for message indetifiers
    // Client options
    // .....
    // Will topic
    broker->clean_session = 1;
}

发送代码sn-p为:

// Send the packet
log_status("to send");
if(broker->send(broker->socket_info, packet, sizeof(packet)) < 
    sizeof(packet)) {
    log_error("send() failed");
    return -1;
}
log_status("send() done");

即使电缆连接断开,我也看不到“send() faied”消息显示。也就是说,我无法确定套接字是否仍然有效。它有什么问题?

【问题讨论】:

  • 与您的问题相关的所有 MQTT 内容是什么?你能减少你的例子吗!是关于通过 UDP 或 TCP 中的 posix 套接字发送...我没有太多乐趣阅读您的所有代码以获取您真正在做什么的信息!
  • 因为send() 只缓冲数据。只有在 ACK 定时器超时时才认为连接断开,在相应的发送之后可能需要相当长的时间。
  • 我重新陈述我的问题:拔掉网络连接后,应用程序级通信中断,插回网络连接后无法恢复通信。但正如我所说,我可以'没有从 send() 获得失败返回,所以我无法恢复应用程序级通信。我能做些什么?如何检测通信中断以及如何恢复?服务器不是我实现的。
  • 我重申我的评论。因为send() 只缓冲数据。如果您有新问题,或者“无法恢复应用程序”之类的新问题,则需要明确说明,可能是新问题。

标签: linux sockets


【解决方案1】:

我使用getsockopt() 来检查套接字的有效性,而不是检查send() 的返回值。有用。在知道socket无效后,我关闭它并重新创建。

代码来自 Simone How to find the socket connection state in C?

int error = 0;
socklen_t len = sizeof (error);
int retval = getsockopt (socket_fd, SOL_SOCKET, SO_ERROR, &error, &len);

/// ....
if (retval != 0) {
    /* there was a problem getting the error code */
    fprintf(stderr, "error getting socket error code: %s\n", strerror(retval));
    return;
}

if (error != 0) {
    /* socket has a non zero error status */
    fprintf(stderr, "socket error: %s\n", strerror(error));
}

【讨论】:

  • 这只是返回套接字上的最后一个错误。您必须在某处忽略错误返回。它不会返回连接的当前状态,因为 TCP 中没有任何这样的东西。所有这些都已在您的链接中说明。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-10-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-25
  • 2017-05-07
相关资源
最近更新 更多