2016-09-16 10 views
0

sendを使用する前にソケットが書き込み可能かどうかを確認しようとしています。ソケットの読み込みバッファがいっぱいでない限り、これはうまくいきます。少なくともselectのタイムアウトです(少なくともそれは私が期待しているものです。つまり、動作は、recvを使わないで多くのデータを送信した後です.selectは0を返します。もう一度やり直してください。通常は再び動作します)。私は、完全な読み取りバッファが送信を妨げないことを期待しています。何が間違っているのですか?読み取りバッファがいっぱいになっているときにselectで書き込み可能なソケットを確認してください

int testwriteable(SOCKET socket) { 
    timeval timeout; 
    timeout.tv_sec = 0; 
    timeout.tv_usec = 100; //100 us (microseconds) 

    fd_set set; 
    FD_ZERO(&set); 
    FD_SET(socket, &set); 

    //check for writable 
    return select(1, NULL, &set, NULL, &timeout); 
} 
+1

再現できません(Win 10 64ビット、VS 2015 R3)。この全機能は私にとって打撃を与えますが、あなたは単一のソケットで多くの作業を行い、返される情報の価値は疑わしいものです。おそらくあなたはあなたの関数がSOCKET_ERRORを返すのをチェックしていて、ソケットが書き込み可能なので、あなたはそれに提示したいデータの*すべて*を受け入れるだろうと仮定していませんか? – kfsone

答えて

1

select()がこのコードでタイムアウトすると、送信バッファがタイムアウトの期間中いっぱいになったことを意味します。

これは間違っています。あなたはコードを駆動するメインのselect()ループを持っていなければなりません。これは制御の逆転ではなく、(a)書くときに書きます。(b)-1/EWOULDBLOCK/EAGAINを返します。その時点でソケットFDをwriteFDsに追加し、ソケットが書き込み可能になるまで書き込みを延期します。それが起こったら、書き込みを再試行し(データとその長さをどこかにキューイングしたことを意味します)、成功した場合はソケットFDをwriteFDsから削除してください。

+0

'は送信バッファが満杯であったことを意味し、ペダンティックであることを意味し、' send'、 'sendto'または' WSASendto'がブロックすることを示します。これは、非ブロック 'connect()'が終了していない。 – kfsone

+0

@kfsone正しい。しかし、この場合、彼は読み取りバッファがいっぱいであることを知っている。これは完全な接続を意味する。 – EJP

+0

私は、リードバッファが一杯になったときに、送信側でブロックされた側から問題が発生したと考えています。相手側の送信部分はデバッグテストであるため、読み取りスレッドを送信し、ブロックをブロックし、送信バッファが実際にデータが読み込まれるまで最終的に満たされるようにします。どのように正確に '選択 'と他のものがうまくいくのかわからないと、問題を誤解させてしまいます。物事を行う正しい方法を指摘してくれてありがとう、私は 'ioctlsocket'(ウィンドウ上)について知らず、少し読んでコードの一部を書き直そうとします。私は通常、C++/winapiコードを書いていません。 – ASDFGerte

関連する問題