
こんにちは。
非同期のプロセス間通信(パイプ)で詰まっています。
環境はWindowsで処理系はC++(Win32)です。
スレッドを用意して、
hPipe = ::CreateFile( L"\\\\.\\pipe\\pipename", GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL ) ;
で作成し、OVERLAPPED構造体を
//
ZeroMemory( &so, sizeof( OVERLAPPED )) ;
sOverlapped.hEvent = ::CreateEvent( NULL, FALSE, FALSE, NULL ) ;
として、
const size_t bufsize = 16 ;
BYTE buffer[ uBufSize ] ;
DWORD dwNumberOfBytesRead ;
bRet = ::ReadFile( hPipe, buffer, bufsize, &dwNumberOfBytesRead, &so ) ;
で読み込みをしています。ReadFile関数はすぐ戻りbRetはFALSEで返ってくるため、GetLastErrorを調べて、
switch( ::GetLastError())
{
case ERROR_IO_PENDING :
bRet = ::GetOverlappedResult( hPipe, &so, &dwNumberOfBytesRead, FALSE ) ;
break ;
}
としてWaitForMultipleObjectsでsOverlapped.hEventがシグナル状態になったら取得したデータの処理をしています。
シグナル状態になるならないに関わらず、上記のReadFileとGetOverlappedResultはループでぐるぐる回しています。
上記の状態で短いデータならよかったのですが、上記のReadFileで読み込み最大サイズの16バイトを超えてしまとうと、
残りの部分のみしか取得できませんでした。
0123456789ABCDEFabcdefg
というデータを受信しようとしたとき、後半のabcdefgだけしか取得できませんでした。
すべてのデータを正しく取得するにはどのようにしたらよいのでしょうか?
A 回答 (2件)
- 最新から表示
- 回答順に表示
No.2
- 回答日時:
TeijigoTeatimeさん、こんにちは。
提示されたコードは受け側のコードですね。
送り側はどうやってますか?
CreateNamedPipeでパイプを生成している思いますが、その第5、第6引数に何を与えていますか?
パイプで送受信するバッファが16バイトしか用意されていないということはないですか。
この回答への補足
こんばんは。レスありがとうございます。
CreateNamedPipeは以下で作成しています。
hPipe = ::CreateNamedPipe( "\\\\.\\pipe\\commandersvc", PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE, 10, 1024, 1024, 100, &secAttr ) ;
受信側で取りこぼしている感じがしてので上記のような質問をさせていただきました。
原因がわかりました。
オーバーラップで処理しているので
case ERROR_IO_PENDING :
のあとで、きちんとイベント待ちしてから処理すれば取得できることができました。
返答頂いたことでいろいろ考えることができました。
ありがとうございました。
No.1
- 回答日時:
dwNumberOfBytesReadの数値はどうなってますか?
この回答への補足
こんにちは。
dwNumberOfBytesReadは7です。"abcdefg"だけが受信できている感じです。
受信側でずっとdwNumberOfBytesReadの中身を監視しても前半の部分が取得された形跡はありませんでした。
送信側では
bRet=::WriteFile(hPipe, "0123456789ABCDEFabcdefg",23,&dwWritten,&so) ;
で送信していますが、dwWrittenは23となっており全て送信されている感じです。
1回目のReadFileで"0123456789ABCDEF"が取得でき、2回目で残りを受信と期待していたのですがその通り動作していません。
原因がわかりました。
オーバーラップで処理しているので
case ERROR_IO_PENDING :
のあとで、きちんとイベント待ちしてから処理すれば取得できることができました。
返答頂いたことでいろいろ考えることができました。
ありがとうございました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
【ExcelVBA】値を変更しながら...
-
エクセル・グラフの 横軸に値を...
-
DataGridの全行編集状態での行追加
-
oo4oによるBLOBデータ取得
-
VBAでMODE関数をつくる
-
構造体配列内の文字列検索のよ...
-
2つ目のレコードの値を取得す...
-
c言語で自分のホームディレク...
-
アクセス ステータスバーの文...
-
C#,繰り返し処理での最大値の取...
-
「テーブルに主キーがありませ...
-
他のMDBのテーブルに追加したい
-
VBからID3タグをいじる方法
-
レコードセットの中身を配列に...
-
COBOLのコーディングについて
-
Access :ALTER TABLE で作成...
-
INT64対応のprintf系関数はあり...
-
VBA 変数名に変数を使用したい。
-
C#で作成したdllをVBScriptで使...
-
スロットマシンの判定方法(VB...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
【ExcelVBA】値を変更しながら...
-
VBAコンボボックスの内容が反映...
-
VBAでアクセスDBからデータの取...
-
【C#】textBoxの指定行のデータ...
-
「Nullの使い方が不正です」の...
-
C# DataTableに最後に追加した...
-
【VB.NET】Excelの最終行までの...
-
VB2010で、選択した系列を最前...
-
非同期のプロセス間通信(パイプ...
-
COBOL数値転記の仕様
-
エクセルのマクロ コンボボッ...
-
エクセルのセル最終行取得
-
ListViewで表示されたデータの...
-
クリスタルレポートでレコード...
-
Excel VBAで1週間毎にカテゴリ...
-
アクセスでウェブ上のデータを...
-
エクセルのCSV読み込みについて
-
[リボンのキーボード ショート...
-
Web画面のTableから数字を取得...
-
Excel VBAでフォルダ内の全テキ...
おすすめ情報