問題タブ [iocp]
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.
c++ - WSARecv が一度に受信できる最大バイト数は?
私は std::vector を使用して、IO データ構造ごとにバッファーを表しています。
最大サイズを指定して、WSARecv() を呼び出した後に m_vecBuffer で「縮小して合わせる」を実行したい。
このページを見ましたが、探している情報が見つかりませんでした。
c++ - 複数の操作が同じソケットに投稿された場合の対処方法
1 つのソケットを管理するクライアント アプリケーションを開発しています。IOCP を使用して非同期 I/O を管理しています。
これは、ネットワーキング プログラミングの本からの引用です。
重複するすべての操作は、アプリケーションが発行した順序で実行されることが保証されます。ただし、完了ポートから返される完了通知が同じ順序であるとは限りません。つまり、アプリケーションが 2 つのオーバーラップした WSARecv 操作 (1 つは 10 KB バッファー、次は 12 KB バッファー) を送信した場合、10 KB バッファーが最初にいっぱいになり、次に 12 KB バッファーが続きます。アプリケーションのワーカー スレッドは、10 KB 操作の完了イベントの前に、12 KB WSARecv の GetQueuedCompletionStatus から通知を受け取る場合があります。もちろん、これはソケットに複数の操作がポストされた場合にのみ問題になります。
では、この場合の対応はどうすればよいのでしょうか。
c++ - IOCP と上書きバッファ
さて、次の詳細でクライアント接続を処理するための IOCP を作成します。
だから私は着信パケットをデバッグしようとしていますが、少し厄介な詳細を除いて、魅力のように機能します... WorkersThread関数にブレークポイントを設定します(パケットを受信する場所)パケットでバッファを監視していますi recv、クライアントから取得した新しいパケットで突然バッファが上書きされたとき。
何故ですか?私が読んだことによると、IOCPはパケットを処理するまで待機し、他のパケットを受信する前にクライアントに応答を送信する必要があります。そのため、「処理中」と呼ばれるソケット コンテキストにフラグを設定しても、着信パケットで上書きされたバッファが取得されます。そのため、まったくデバッグできず、気が狂ってしまいます
ollydbg (デバッガー) の障害で、ブレークポイントを設定している間に他のスレッドを実行できますか? または、私の IOCP 実装に何らかのエラーがありますか?
WorkerThread のコーディング方法は次のとおりです。
clientinfo->RecvContext.Bufferを見ると問題が発生します。私はパケットを監視しており、数秒後にバッファが新しいパケットで上書きされます。
ありがとう !
c++ - 呼び出しスレッドをアラート可能な待機状態にする
私のメイン スレッドは、複数の I/O ワーカー スレッドを作成します。次に、次のようにして、メイン スレッドから I/O 要求を開始します。
I/O ワーカー スレッドのある時点で、要求が完了し、IoRequest オブジェクトのバッファーが有効な応答データで満たされます。
WSASend() を呼び出した後、メイン スレッドをアラート可能な待機状態にし、準備ができたらいつでも応答データを受信できるようにするにはどうすればよいですか?
c++ - IOCP を使用する場合、WSAOVERLAPPED の hEvent を NULL に設定するか、WSAEVENT オブジェクトへの有効なハンドルに設定する必要がありますか?
MSDNによると:
hEvent : オーバーラップされた I/O 操作が I/O 完了ルーチンなしで発行された場合 (操作の lpCompletionRoutine パラメーターが null に設定されている)、このパラメーターには WSAEVENT オブジェクトへの有効なハンドルが含まれているか、null である必要があります。
私は IOCP を使用しているので、WSASend() または WSARecv() を呼び出すときに、最後のパラメーター (つまり、lpCompletionRoutine) に NULL を渡します。
「I/O データごと」のクラス (pIoRequest) は次のようになります。
上記の A、B、C の行をコメントアウトしても、プログラムの動作に違いはないようです。
では、いつ WSACreateEvent() を呼び出すか、単に hEvent を NULL に設定するかをどのように決定すればよいでしょうか?
c++ - std::shared_ptr を使用して I/O データごとに IOCP でラップできますか?
IOCP を使用するクライアント アプリケーションに取り組んでいます。
I/O ごとのデータ クラスは、WSAOVERLAPPED から派生しています。
非同期 I/O 操作を実行するときは、次のように使用します。
IoRequest インスタンスをワーカー スレッド ルーチンで再利用します。I/O ごとのデータを管理するために生のポインタの代わりに std::shared_ptr を使用しても問題はありませんか?
したがって、WSASend() の場合は次のようになります。
乾杯
c++ - GetQueuedCompletionStatusは、最初にIOを発行したスレッドがWindows 8のReadFileでブロックしている場合、IOCPからIOをデキューできません。
Windows 8に切り替えた後、アプリが動作を停止します。問題のデバッグに何時間も費やしましたが、IOCPの動作がWindows8と以前のバージョンで異なることがわかりました。問題を実証および再現するために必要なコードを抽出します。
このプログラムはポート1999でリッスンし、非同期accpetを発行してから、ブロッキングパイプを読み取ります。このプログラムをWindows7、8、XP、2003、2008でテストしました。「telnet127.0.0.1 1999」の後、「dequeued aIO\n」がWindows8以外のコンソールに出力されます。
重要なのは、非同期操作を最初に発行したスレッドがReadFileでブロックしてはならないことです。そうしないと、ReadFileがWindows 8に戻るまで、GetQueuedCompletionStatusがそのIOをデキューすることはありません。
また、パイプを読み取る代わりに「scanf」を使用してテストしました。「scanf」は最終的にコンソールを読み取るためにReadFileを呼び出すため、結果は同じです。影響を受ける関数がReadFileだけなのか、他の関数があるのかわかりません。
私が考えることができるのは、専用スレッドを使用して非同期操作を発行することです。すべてのビジネスロジックは、その専用スレッドと通信して、accept / send/recvを実行します。しかし、余分なレイヤーは余分なオーバーヘッドを意味します、Windows 8の以前のバージョンのWindowsと同じパフォーマンスを達成する方法はありますか?
.net - SocketAsyncEventArgs.Completed doesn't fire in Windows 8
When I compile this code on a machine with Windows 7 Ultimate and .NET 4 installed, it works just fine but when I try it on one with Windows 8 RTM and .NET 4.5 installed, Complete event never fires.
The interesting thing here is if I put a breakpoint at this line and debug it:
And connect this server using Hercules before continuing execution, it works like a charm. I do this at the start and then magically, OnAccepted gets called and writes "Accepted." to the console on every single connection. I use the same code and same program (Hercules) on the machine with Windows 7 and .NET 4 but it always works.
- Am I doing something wrong?
- If not, is it a known bug of my OS or .NET Framework version 4.5?
- Can anyone reproduce this?
Edit: Both operating systems are 64 bit.
Edit 2: I reported this as a bug on Microsoft Connect, here.
Edit 3: Found a workaround and post it to Connect (Simply by creating a fake, first connection).
Edit 4: If anyone can reproduce this, please join the issue in Connect.
Edit 5: I saw the question Thomas has mentioned and I tested whether Console.ReadLine
was causing this or not. Turned out it was. If I add Thread.Sleep(3000)
before my Console.ReadLine
call and make a connection attempt in 3 seconds after I run the program, it works like a charm. Again, the odd thing is that I need to do this only once before calling Console.ReadLine
. If I make one connection before calling Console.ReadLine
then every consecutive connection works, even after Console.ReadLine
is called. I'll mention this in the Conect page.
Edit 6: I added the link to the other question to the Connect page and added another workaround that involves calling Thread.Sleep
before calling Console.ReadLine
like I mentioned in the above edit.
c# - 低レベルAPI(I / O完了ポートなど)と相互作用するコードをデバッグするにはどうすればよいですか?
Socket
の一連のメソッドを使用するコンソールアプリケーションを作成しましたが *Async
、時々クラッシュします。同期されたコードのように例外がどこにスローされたかは表示されません。コンソールがシャットダウンするだけで、何が間違っているのかわかりません。
try
/catch
ブロックをどこに置くかを知らなくても、このような非同期操作に関して例外を検出する方法はありますか?
必要なのは、コードのどの部分がアプリケーションをクラッシュさせるかを知ることだけです。
編集:
未処理の例外の通常のことは、Visual Studioを使用してコードをデバッグしているときに、実行を一時停止し、例外(または少なくとも例外メッセージ)の原因となったコード行を表示することです。ただし、状況によっては(IOCPなどの低レベルAPIとの対話など)、プログラムがクラッシュし、原因に関する情報がないままデバッグが終了する場合があります。
私が必要としているのは、その特定の例外を確認する方法です。
「何が起こったのか、どこで(どのメソッドで)起こったので、プログラムがクラッシュしたのですか?」
ですから、「何を間違えたのか」ではなく、「何を間違えたのかをどうやって知ることができるのか」と問いかけます。
- 例外がスローされた時点で実行を中断できますか?
- クラッシュ後の呼び出しスタックを確認して、原因となったメソッドを特定できますか?
- このような状況を回避するためのアドバイスをお願いします。