私は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() 呼び出しのパフォーマンスを向上させるためにできることはありますか?