問題タブ [recv]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
http - recv() が最初のループを除くすべての for ループ反復で '0' バイトを返すのはなぜですか?
私は C++ で小さなネットワーク プログラムを書いています。とりわけ、Twitter のプロフィール写真をダウンロードする必要があります。URL のリスト (stl::vector) があります。次のステップは、for ループを作成し、ソケットを介して GET メッセージを送信し、画像を別の png ファイルに保存することだと思います。問題は、最初のメッセージを送信し、回答セグメントを受信し、png データを保存すると、すべて問題ないように見えることです。しかし、次の反復で、同じソケットを介して送信された同じメッセージは、recv() 関数によって 0 受信バイトを生成します。サイクル本体にソケット作成コードを追加することで問題を解決しましたが、ソケットの概念について少し混乱しています。メッセージを送信すると、ソケットを閉じて再作成し、次のメッセージを同じサーバーに送信する必要があるようです(次の画像を取得するため)。これはソケットの正しい方法ですか '
前もって感謝します。
UPD:これは、ソケットを作成するループを含むコードです。
linux - linux recv()関数フラグパラメータ?
recv(sockfd, buffer, len, 0);
非ブロッキングソケットで使用するとどうなりますか?
ソケットsockfd
が閉じているか、何も読み取られない場合、recv()
ブロックは実行されますか?(注:のフラグはrecv ()
です0
)。
c++ - サーバーデーモンのソケットが機能しなくなりました
6961 と 6963 の 2 つのポートをバインドするアプリケーションがあります。これは、一方のクライアントがもう一方のクライアントを制御するクライアント-サーバー-クライアント形式のアプリケーションです。
アプリケーションは問題なく動作していますが、一見ランダムな量の接続が受け入れられ閉じられた後、サーバーはソケットを介したデータの送受信を拒否します。と接続できますが、telnet
何か入力しても応答がありません。
サーバーが動作を拒否するまで最大 370 の接続を受け入れたことがありましたが、前回は 70 の接続しか受け入れませんでした。
ソケットを閉じることとは関係ないと思いますが、それは適切に行っていると思います。これは、アプリケーションを起動したときの出力ですnetstat
。lsof
しかし、私はそれらをどのように解釈するかについての手がかりを本当に持っていません。私はグーグルでこれらを見つけました。
これは、サーバーが受け入れを停止したときの両方のコマンドの出力です。
どこからバグを探し始めればよいかわかりません。
c++ - Winsockのsend()/recv()を利用する場合、確認応答は必要ですか?
Winsock、C++ を使用して、send()/recv()、TCP 接続でデータを送受信します。データが相手に届いたことを確認したいのですが、 recvでデータを受信した後 (if) に確認メッセージを返信することをお勧めします。
ここに 2 つの可能性があります。どちらに進むべきかアドバイスをお願いします。
sendが渡されたバッファのサイズを返す場合、データは少なくともワイヤの反対側のrecv関数に配信されていると想定します。「少なくとも」と言うとき、recvがそこで失敗したとしても(たとえば、バッファ不足などのために)、気にしないで、サーバーの一部の作業を適切に完了したことを確認したいだけです-データを完全に送信しました (つまり、データが他のマシンに到達しました)。
追加の確認応答を使用します。recvでデータを受信した後、受信したパケットの ID (送信された各データのヘッダーの一部) を送り返し、そのパケットの受信操作が成功したことを通知します。一定の間隔を置いてもそのような「確認メッセージ」を受信しない場合は、送信者関数から失敗コードを返します。
2 番目の回答の方が安全に見えますが、転送プロトコルが冗長である場合に複雑にしたくありません。また、TCP 接続について話していることにも注意してください (UDP よりも安全です)。
データが反対側のrecv関数に配信されたことを保証する他のメカニズム(おそらく他のAPI?おそらくWSARecv()/WSASend()の動作?)はありますか?
2 番目の方法をお勧めする場合は、recvをタイムアウト付きで使用して確認応答を受信できるようにするコード スニペットを教えてください。recvはブロッキング操作であるため、前回の送信試行が失敗した場合 (相手に通知されなかった場合) は永久にハングします。タイムアウトを指定してrecvを使用する簡単な方法はありますか(毎回個別のスレッドを作成することなく、おそらくすべての送信操作でやり過ぎになるでしょう)。
また、関数を送信するために渡すデータの量は非常に大きい (数メガバイト) 可能性があるため、「確認メッセージ」のタイムアウトを選択するにはどうすればよいですか? 大きなバッファを「分割」して、いくつかの送信呼び出しを使用する必要がありますか? かなり複雑になると思いますので、アドバイスお願いします!
編集: わかりました、あなたは TCP/IP スタックがそれを処理することを示唆しています(つまり、手動の承認は必要ありません)、これは私が MSDN ページで見つけたものです:この関数は、データが正常に送信されたことを示すだけです。」したがって、TCP メカニズムにデータ配信を保証する機能があるとしても、 send()関数やその他の Winsock 関数を介してそのステータス (成功かどうか) を取得することはできません。TCP層からステータスを取得する方法を知っていますか? 繰り返しますが、send()関数の戻り値が十分ではないようです!
================================================== ======
編集 2: OK、TCP プロトコルは何か問題が発生した場合のエラー処理を考慮しますが、Winsock のsend()関数はエラーを報告できないことに同意すると思います(単純に、実際のデータ送信が開始される前に返されるためです)。ネットワークドライバー)。ここで百万ドルの質問があります: Winsock のsend()関数は、少なくとも、現在のパケットが配信されるまで、他のパケットが相手に配信されないことを保証しますか? 言い換えれば、何らかのネットワーク障害で送信が失敗した場合 (しかし、send()呼び出しによって報告されない)、次のデータのチャンクでsend()関数の次の呼び出しの前にネットワーク障害が修正されます。前のパケット (失敗しましたが、によって報告されていません)send() ) は次のパケットの前に配信されますか? つまり、1 つの特定の send() 関数が「黙って」失敗し、後続の send() 呼び出しが成功しても最初のパケットが失われる可能性はありますか? 繰り返しますが、私は TCP レベルで話しているのではなく、Winsock API レベルで話しているのです!
multithreading - 複数の論理データ ストリーム (Winsock) に単一ポートを使用する方法は?
ネットワーク経由でさまざまな種類のデータ (ビデオ ストリーム、オーディオ ストリーム、サービス通知など) を送信するクライアント サーバー Winsock アプリ (Visual C++) を開発しています。よりクリーンなアプローチは、個々のデータ型ごとに個別のスレッドで個別のポートを使用することであることを知っています (ここでは「ストリーム」と呼びます)。ただし、これには少なくとも 5 つの異なるポートを占有する必要があり、一部のネットワーク インフラストラクチャ (ファイアウォール ポート フォワーディングなど) で問題が発生する可能性があります。
だから私は1ポート接続(TCP)を実装しようとしています.1つのソケットだけが異なるストリームを送信するために使用されます. 個々のパケットには、それが属するストリーム、予想される合計メッセージ サイズなどを示す情報がヘッダーに含まれます。5 つの異なるストリームがあるとします。同じソケットのsend()を呼び出すために 5 つのスレッドを使用する予定です。これは安全ですか?異なるストリームからのパケットが混在して到着することはわかっていますが、送信された各パケットに必要なメタ情報を含めると、反対側で適切に再構築できますよね?
しかし、本当の問題は受信側です。同じソケットで複数のスレッドからsend()を呼び出すことはおそらく問題ありませんが (よくわかりませんので確認が必要です!)、複数のスレッドからrecv()を呼び出すことはあまり意味がありません。したがって、1 つのスレッドから 1つのブロッキングrecv()を使用する必要があります。しかし、パケット ヘッダー (特定のパケットが属しているストリームを特定する) に基づいて、異なるスレッドで処理をフォークする必要があります。ビデオ ストリームは 1 つのスレッド、サウンド ストリーム - 別のスレッドなどで処理する必要があります。パフォーマンスが最優先事項であるため、すべてのストリームを 1 つのスレッドで処理することは考えられません。
要約すると、次の 3 つの質問があります。
- 複数のスレッドから同じソケットに対してsend()を呼び出しても問題ありませんか? (どの送信側スレッド (つまり、サブシステム) に属しているかに関する情報がパケット ヘッダーに含まれていると仮定します)。
- 受信側に1 つのブロッキングソケットを持ち、単一のスレッドからループ内でrecv()を呼び出すと、異なる論理ストリームの受信パケットを異なるワーカー スレッドに「フォーク」する方法は?
- 1 つのポートを介して複数のストリーム転送を実装するための追加の推奨事項は何ですか?
PS: 確かに、1 つのポートを複数のソケットで使用する方法はありませんね。
それは、Windows プラットフォーム、Winsock2、Visual C++ です (プラットフォーム固有の素晴らしいヒントを提供できれば)。
=更新=
「ソケットをロックする」とは、send()関数へのアクセスをシリアル化するということですか? たとえば、クリティカル セクションで?
受信側については...メッセージを組み立てると思います(ビデオフレームやサウンドサンプルなどの論理的な完全なデータ構造を「メッセージ」と呼びます)。個々のストリームを個々のバッファーに)、次に、組み立てられたメッセージを (メッセージが完全に受信されたときに) フォーク スレッドに渡します。それが問題です - それらを渡す方法。私が考えた 1 つの方法は、イベント オブジェクトです。レシーバー スレッドからSetEvent()を呼び出して、 WaitForSingleObject()をトリガーします。(これはいくつかのループにあります)異なるスレッドで。これが許容できる解決策であるかどうかアドバイスできますか? もっと良いものを提案できますか?これを行う (同じアプリケーションの別のスレッドを「トリガー」する) ためのより高速なソリューションは、イベント オブジェクトよりもありませんか? そして、どのようにデータを渡すのですか?
sockets - ソケット: サーバーのシャットダウン時に、クライアントはリターンなしで終了します
私は単純なクライアント/サーバー TCP 通信ストリームを作成していますが、私の問題は、サーバー アプリを強制終了すると、クライアント アプリが正常に終了することです。STDERR への出力はなく、recv() は 0 または -1 を返さず、クライアント アプリは停止するだけです。
一方、クライアント アプリを強制終了すると、サーバー アプリは send() から 0 の戻り値を取得しますが、これは想定どおりです。
この問題に関するヘルプは大歓迎です!
python - Python tcp 送受信関数
Pythonでは、recvはブロッキング関数ですか? 私はUni Cで学びましたが、そこにはブロッキングソケットとノンブロッキングソケットがありました。だから私はただPythonで天気を尋ねたいだけですrecv関数はブロッキング関数かどうか.
c - ソケットが閉じているときに recvfrom のブロックを解除する
ポートで受信するスレッドを開始するとします。ソケット呼び出しは recvfrom でブロックされます。次に、どういうわけか別のスレッドで、ソケットを閉じます。
Windows では、これにより recvfrom のブロックが解除され、スレッドの実行が終了します。
Linux では、これは recvfrom のブロックを解除しません。その結果、私のスレッドは永遠に何もせずに座ったままになり、スレッドの実行は終了しません。
Linux で何が起こっているのか、誰か助けてもらえますか? ソケットが閉じられたら、recvfrom にブロックを解除してもらいたい
select() の使用について読み続けていますが、特定のケースでの使用方法がわかりません。
c++ - BSDソケット-sendとrecvの使用
私はbsdソケットを使用してLinuxで簡単なチャットプログラムを実装しようとしています。現在、クライアントからサーバーに1つのメッセージを送受信しようとしています。コードを実行するたびに、recvは-1を返し、errnoコードは22です。
サーバーコード-
クライアントコード-
サーバー側でエラーが発生しても、クライアント側ではエラーメッセージが表示されません。正常に終了します。
-http ://www.workers.com.br/manuais/53/html/tcp53/mu/mu-7.htmによると 、errno22エラーメッセージは単に「無効な引数」を意味します。しかし、それをどのように正確に解釈するかはわかりません...引数が無効だった場合、なぜそれがコンパイルされるのでしょうか?
私がここで間違っていることを誰かが指摘できれば、私はとても感謝しています。そして、あなたが指摘したいと思う他の小さなメモは歓迎されます。助けてくれてありがとう。
timeout - recv() Windowsソケットには無限の時間がかかります - タイムアウトする方法は?
ファイル記述子を使用して読み取り可能なソケットを見つけ、読み取りを続けます。何らかの理由で、ワイヤ上にデータがないソケットは読み取りを続行し、決して返されません。タイムアウト後に受信から抜け出す方法はありますか?
私はwinsockライブラリを使用しています..