ローカルネットワーク上のデバイスへの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はそのEthernetインターフェイスに珍しいパケットを表示しません(参照)https://pastebin.com/kTfwc5srここで、10.0.0.100 は関連していない別のデバイスです。

connect() 呼び出しのパフォーマンスを向上させるためにできることはありますか?

ベストアンサー1

おすすめ記事