TCP connect() 调用本地网络上的设备非常慢

TCP connect() 调用本地网络上的设备非常慢

我正在 Debian linux 上使用 isc-dhcp-server 运行本地 DHCP 服务器,地址 10.0.0.1。我在 10.0.0.99 上有一个中继,每 4 秒左右通过 HTTP 请求向该中继发送一个脉冲。

伪代码的工作原理如下:

while (1) {
    get curr_time
    if ((webrelay->socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) <= 0) {
        log_perror(MYNAME "socket invalid for webrelay %i", webrelay->webrelay_id);
        usleep(4000 * 1000);
        continue;
     }
    if ((flags = fcntl(webrelay->socket, F_GETFL, 0)) == -1) 
        log_error("fcntl fail for webrelay");
    else
        fcntl(webrelay->socket, F_SETFL, flags | O_NONBLOCK);

    if (setsockopt(webrelay->socket, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(one)) < 0) 
            perror("setsockopt fail for webrelay");

    relay_socket.sin_family = AF_INET;
    relay_socket.sin_port = htons((unsigned short)webrelay->net_port);
    relay_socket.sin_addr.s_addr = webrelay->net_address.s_addr;
    if (connect(webrelay->socket, (const struct sockaddr*)&relay_socket, sizeof(relay_socket)) < 0) {
        switch (errno) {
        case EINPROGRESS:
            while (1) {
                if time_now - curr_time > 4 seconds, 
                    print "connect slow", close socket and next iteration of for loop
                else 
                    fds[0].fd = webrelay->socket;
                    fds[0].events = POLLIN | POLLOUT;
                    fds[0].revents = 0;
                    if (poll(fds, sizeof(fds) / sizeof(fds[0]), 1) < 0) {
                        log "connect fail", close socket and next iteration of for loop
                    }
                    if (fds[0].revents & (POLLIN | POLLOUT))
                        break;
        case OTHER_ERROR_HANDLING:
            these cases never get called
        }
    }
    send(webrelay->socket, state_xml, sizeof(state_xml), MSG_DONTWAIT) //and perform error checks
    shutdown(webrelay->socket, SHUT_RDWR);
    close(webrelay->socket);
    webrelay->socket = 0; 
    //wait short amount and to next iteration
}   

不幸的是,在让计算机打开多天后,我不断从 connect() 中收到这些 EINPROGRESS 错误,这意味着 connect() 需要花费几秒钟的时间。如果我将连接设置为正常阻塞模式,则会在 connect() 调用上收到超时错误。结果,继电器关闭,因为连接需要很长时间,并且最后一个脉冲在发送新脉冲之前就过期了。

所有其他网络功能调用都可以无缝工作,并且据我所知,tshark 在该以太网接口上没有显示任何异常数据包(请参阅https://pastebin.com/kTfwc5sr,其中 10.0.0.100 只是另一个不相关的设备)。

我可以做些什么来提高 connect() 调用的性能吗?

相关内容