로컬 네트워크의 장치에 대한 TCP connect() 호출이 매우 느립니다.

로컬 네트워크의 장치에 대한 TCP connect() 호출이 매우 느립니다.

저는 isc-dhcp-server, 주소 10.0.0.1을 사용하여 Debian Linux에서 로컬 DHCP 서버를 실행하고 있습니다. 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() 호출의 성능을 향상시키기 위해 할 수 있는 일이 있습니까?

관련 정보