2

アプリケーション(winsock2.h)にWindowsソケットを使用しています。ブロッキングソケットでは接続タイムアウトを制御できないため、非ブロッキングソケットを使用しています。コマンドを送信した直後に、shutdownコマンドを使用してフラッシュしています(実行する必要があります)。タイムアウトは50ミリ秒ですが、送信するデータが非常に大きい場合、データの一部のみを送信したり、何も送信しなかったりするリスクはありますか?前もって感謝します...

    hSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    u_long iMode=1;
    ioctlsocket(hSocket,FIONBIO,&iMode);
    connect(hSocket, (sockaddr*)(&sockAddr),sockAddrSize);
    send(hSocket, sendbuf, sendlen, 0);
    shutdown(hSocket, SD_BOTH);
    Sleep(50);
    closesocket(hSocket);
4

2 に答える 2

1

非ブロック TCP ソケットと送信直後のフラッシュ?

TCP ソケットをフラッシュするようなことはありません。

ブロッキングソケットでは接続タイムアウトを制御できないため

間違い。select()ブロッキングソケットで使用できます。

ノンブロッキングのものを使用しています。

非間隔。

send コマンドの直後に、shutdown コマンドを使用してフラッシュしています (必要があります)。

する必要はなく、shutdown()何もフラッシュしません。

私のタイムアウトは50msです

なんで?データの送信にかかる時間は、データのサイズによって異なります。明らかに。送信に固定タイムアウトを使用しても意味がありません。

私が知りたいのは、送信するデータが非常に大きい場合、データの一部のみを送信するか、まったく送信しないリスクがあるかということです。

ブロッキング モードでは、提供されたすべてのデータがsend()可能であれば送信されます。ノンブロッキング モードでは、send()可能な場合、戻り値によって表されるデータ量が送信されます。いずれの場合も、送信に失敗すると接続がリセットされます。どのようなタイムアウトメカニズムを重ねても、それを変更することはできません。具体的には、タイムアウト後にソケットを非同期に閉じると、送信されるデータにクローズが追加されるだけです。送信が中止されることはありません。

あなたのコードは、誰もが知っているコードレビューに合格しません。エラーチェックはありません。睡眠は完全に無意味です。閉じる前にシャットダウンするのは冗長です。スリープがタイムアウトを実装することを意図している場合、そうではありません。

できるだけ早くデータを送信したい。

できません。TCP はフロー制御を実装します。それについてあなたができることはまったくありません。受信者によってレート制限されています。

また、考えられる2つのケースは次のとおりです。サーバーが接続を受け入れるのに時間がかかりすぎる

そのようなケースはありません。クライアントは、サーバーが呼び出す前に接続を完了することができaccept().ます。デフォルトの約 1 分よりも短い接続タイムアウトを実装しようとしている場合は、select().

または受け取ります。

それについてあなたができることは何もありません。上記を参照してください。

私の状況では時間が非常に重要であるため、接続と書き込みの両方を最大50msで行う必要があります。

上記を参照。時間がかかる操作に固定のタイムアウトを実装しても意味がありません。また、50 ミリ秒は接続タイムアウトには短すぎます。それが実際の問題である場合は、接続の遅延が 1 回だけ発生するように、接続を開いたままにしておく必要があります。

書き込みストリームと読み取りストリームの両方をフラッシュする必要があります

できません。TCP には、読み取りストリームまたは書き込みストリームをフラッシュする操作はありません。

サーバーが不必要に大きなデータを送信し続け、インターネット接続が制限されているためです。

別の非 sequitur。サーバーがデータを送信する場合は、それを読み取る必要があります。そうしないと、サーバーが停止します。これは、独自の書き込みストリームのフラッシュとは関係ありません。

実際、サーバーからの1バイトも必要ありません

不運。あなたはそれを読まなければなりません。[BSD Unix を使用している場合は、入力用のソケットをシャットダウンできます。これにより、サーバーからのデータが破棄されますが、Windows では機能しません。サーバーの接続がリセットされます。]

于 2016-01-25T20:44:14.893 に答える
-2

EJP と Martin のおかげで、チェックする 2 つ目のスレッドを作成できました。質問に投稿したコードにも、「counter=0;」を追加しました。「送信」行の後の行と削除されたシャットダウン。それは今私が望んでいたように機能します。50ミリ秒以上待つことはありません:)本当にありがとう

unsigned __stdcall SecondThreadFunc( void* pArguments )

{

while(1)
{
    counter++;
    if (counter > 49)
    {
        closesocket(hSocket);
        counter = 0;
        printf("\rtimeout");
    }

    Sleep(1);
}
return 0;

}

于 2012-07-15T11:56:57.030 に答える