接続されたTCPソケットがノンブロッキングモードになっています。データの送受信は正しく機能します。などの専用スレッドにループとして実装されている受信:select()がタイムアウト時間を超えてブロックされることがある
fd_set fdset;
FD_ZERO(&fdset);
FD_SET(internal->m_socket, &fdset);
struct timeval timeout;
timeout.tv_sec = timeout_ms/1000;
timeout.tv_usec = (timeout_ms % 1000) * 1000;
int ret = select(internal->m_socket + 1, &fdset, nullptr, nullptr, &timeout);
if (ret == 0) {
// handle timeout then loop
} else if (ret < 0) {
// handle error then abort
} else {
ret = recv(...); // Read data available on socket then loop
}
TCPコネクションは、OS X 10.11.5を実行している私のMacBookProからWiFi経由で行きます。接続が確立されている間にWiFiをオフにすると、フォローアップのあるselect()
コールが指定したタイムアウト値よりかなり長くかかることがあります。ここで
IN
と
OUT
を直前にそれぞれ印刷され、タイムアウト値に渡され、実際の測定された経過時間と
select()
後):
(WiFi is ON, thread is continuously receiving from socket)
08:31:15 -------- IN = 15000
08:31:30 -------- OUT = 14999
08:31:30 -------- IN = 15000
08:31:45 -------- OUT = 15000
08:31:45 -------- IN = 15000
08:32:00 -------- OUT = 15000
08:32:00 -------- IN = 15000
08:32:15 -------- OUT = 15002
08:32:15 -------- IN = 1000
08:32:15 -------- OUT = 87 <--- data received
08:32:15 -------- IN = 4913
08:32:15 -------- OUT = 0 <--- data received
08:32:15 -------- IN = 15000
(WiFi is turned OFF at this point in the middle of a `select()` call)
08:32:30 -------- OUT = 15004 <--- ok
08:32:30 -------- IN = 1000
08:32:31 -------- OUT = 1003 <--- ok
08:32:31 -------- IN = 1000
08:32:32 -------- OUT = 1006 <--- ok
08:32:32 -------- IN = 1000
08:32:43 -------- OUT = 10999 <--- NOT OK: 10X longer
08:32:43 -------- IN = 1000
08:32:48 -------- OUT = 4965 <--- NOT OK: 5X longer
(truncated)
注意明白な存在しないことパターン:ときにはバグが起こっていないように見えることがありますが、ほとんどの場合そうです。指定したタイムアウトよりも長くかかったり、その後に1つ以上の時間がかかると、WiFiをオフにした後に即時にselect()
コールを送信することができます。
選択タイムアウトはわずか1秒ですか?どうして? – EJP
このスニペットの上には多くのコードがあり、受信タイムアウトが発生すると他のロジックが実行されています。たとえば、私はデフォルトで15秒のタイムアウトを使用していますが、接続が機能していないとアプリが判断した場合、サーバーにPingを送信し、タイムアウトを1秒に減らし、Pongを数秒待ってから接続を終了します。受信していない。 – Pol
これはApp Napです。問題が発生した時点で、アクティビティモニターの[エネルギー]タブにアプリが表示されているかどうかを確認します。 –