VisualC++6.0にて、PCと通信相手の機械との間で、同期のシリアル通信を行うツールを作成していますが、たまにWriteFile()のデータ送信が完了しない状況になってしまいます。
問題が発生している状況は、以下となります。
・WriteFile()を実行した際、戻り値としてTRUEが返却されるが、書き込んだバイト数が0byteとなっていて、送信できていない。
・上記問題が発生した際でも、ReadFile()でのデータ受信は正常に出来る。
・WriteFile()やReadFile()の実行前後でClearCommError()を実行しても、いずれもオーバーフロー等のエラー情報は検出できない。
・上記問題が発生した際、GetLastError()=0となり、エラー情報は検出できない。
・ツールを最小化したり、IE等のプログラムを立ち上げたりした際に、上記問題が発生しやすい。
・DCB構造体のfDtrControlとfRtsControlをDISABLEやENABLEに変更したが、状況は改善しなかった。
・VisualStudio2005のC++にてツールを作り直したが、状況は改善しなかった。
・処理中にSleep(1)を入れて、WriteFile()とReadFile()の間隔を広げると問題は発生しなくなる。ただし、ツールの処理時間が倍以上となってしまう為、Sleepを入れることでの解決はしたくない。
また、PCと通信相手の機械との間の通信内容は、以下となります。
・上記問題が発生するまでの通信は、正常にできている。
・シリアル通信は、仮想COMポートによるUSB2.0の通信。
・SetCommTimeouts()にて、Read/Write共に、タイムアウト時間を1500msとしている。
・通信相手からの1回あたりのデータサイズは、最大4100kByte。また、5分間で約500MByteのデータがPC側へ通知される。
・PCからは、通信相手からのデータを受信した後、ACKとして8Byteのデータを送信する。
・PCは、USB2.0に対応したWindowsXPとVistaで上記問題が発生することを確認した。
私としては、問題が起こるまでの通信は正常に出来ている点や、Sleepを入れることで、問題が発生しなくなる点から、ツールの不具合ではなく、PC内部でデータ送信できなくなる問題が発生しているのではないかと考えています。しかし、問題の特定には至っていません。
どうか上記問題として考えられる原因や、原因特定の為の調査方法をご教示ください。
よろしくお願いします。
A 回答 (4件)
- 最新から表示
- 回答順に表示
No.4
- 回答日時:
おはようございます。
「仮想COMポート」って事は、RS232Cとかのシリアル通信ではなく、FTDIとかのUSBによる通信なんですよね。
速度もすさまじいですしね。
なんかこうなってくると、ドライバを疑ってみたくなってしまいますが・・・。
同期モードでやられているとの事ですが、シリアル通信は必ず非同期モードで、と、どこかで読んだ記憶があります(多分、速度上の理由であり、本件とは関係ない気もしますが)。
「GetOverlappedResult」で検索すれば、サンプルがいっぱい出てきますので、非同期を完成させてみられてはどうでしょう。
当方では、以下のような感じで正常に通信ができていますので、ご参考になれば。
・相手はFT245BL(FTDI)
・非同期モード
・受信は別スレッド
・通信データ量は質問者様よりはるかに少ないですが、少量のデータをひっきりなしにやり取りしています。
回答ありがとうございます。
私も初めはドライバが処理速度についていけてないのではと考えていました。
その為、別のドライバを使用して動作検証を行ってみましたが、結果は改善しませんでした。
また、使用しているドライバは私が作ったものではなく、ドライバや通信相手の機械を修正することが出来ない為、ツール側で問題を解決したいと考えている次第です。
やはり、高速な通信の場合には、非同期モードにて通信を行ったほうがいいようですね。
非同期モードにて何とか解決できる方法がないかと、本問題の根本原因について、引き続き調査していきます。
No.3
- 回答日時:
WriteFileのリファレンスはちゃんと読まれましたか?
オーバーラップをつかって書き込んだ場合hFileのオープン時にFILE_FLAG_OVERLAPPDを指定し、lpOverlappedに有効なポインタが渡された場合 WriteFileは 0を返します
この時点では まだ転送が完了していないので GetLastErrorもERROR_IO_PENDINGを返し、まだデータ転送が終わっていないことを示します
転送できたどうかは GetOverlappedResultで取得するのですよ
本来ならhEventにCreateEventで作成したハンドルを設定しておいて
WaitForSingleObjectなどでこのイベントハンドルがシグナル状態になるのを待機して、待機が解除されたらGetOverlappedResultで確認
といった手法でしょう
本当にオーバーラップが必要なのでしょうか?
通信相手のマニュアルにはサンプル例などがないのでしょう …
この回答への補足
通信モードは、同期モードにて通信をおこなっています。
(CreateFile()にてFILE_FLAG_OVERLAPPEDを設定していません。)
また、非同期モードにて通信を行うように処理を修正しても、問題は改善しませんでした。
(詳細は、No.2の回答の補足として記載しています。)
No.2
- 回答日時:
こんにちは。
非同期モードでオープンされているのですよね。
概ね非同期通信の想定通りの動作のように思えます。
GetLastErrorが0を返すというのが気になりますが。。。
GetOverlappedResultで、送信完了を待つとかされては、どうでしょう。
この回答への補足
回答ありがとうございます。
通信モードは、同期モードにて通信をおこなっています。
(CreateFile()にてFILE_FLAG_OVERLAPPEDを設定していません。)
また、以下のように非同期モードにてデータ送信を行うようにツールを作り直した事もありました。
(1)WriteFile()にてデータ送信を開始する。
(2)WaitForSingleObject()にてシグナル状態になるまで待機する(1000msでタイムアウト)。
(3)(2)にてシグナル状態になった際に、GetOverlappedResult()にて送信完了したデータサイズを取得する。
上記の結果としては、(2)にてタイムアウトとなり、(3)まで処理が進みませんでした。
その際、GetLastError()=997(ERROR_IO_PENDING)となりました。
また、SetCommTimeouts()やWaitForSingleObject()でのタイムアウト時間を延長しましたが、結果は変わりませんでした。
その為、同期モードでも非同期モードでも発生する問題であると考えて、現状は同期モードにて問題の調査を行っている次第です。
No.1
- 回答日時:
WriteFile()は単にバッファにデータを転送するだけで実際のシリアル通信とは連動しません。
(通常はほぼ同時に終了)ただし他のアプリケーションが動作していたり、最小化していれば実際の通信が終了しないことは十分に有り得ます。
lpNumberOfBytesWrittenがnNumberOfBytesToWritより小さい時Sleepを入れる、GetQueuedCompletionStatus()によって送信完了を確認するなどで解決できるのでは。
この回答への補足
回答ありがとうございます。
lpNumberOfBytesWrittenがnNumberOfBytesToWritより小さい時Sleepを入れるという方法は試してみましたが、解決出来ませんでした。
現状は、WriteFile()でのデータ送信が出来なくなったら、一度USBケーブルを抜かないと
正常にデータ送信できなくなる状況です。
GetQueuedCompletionStatus()というものは、使用したことはありませんが、以下のサイトで存在自体は知っていました。
http://keicode.com/windows/win06.php
しかし、サーバー開発に用いられると説明されていた為、今回のようなシリアル通信には使用できないと思っていました。GetQueuedCompletionStatus()は、シリアル通信にも用いることが出来るものなのでしょうか。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Excel(エクセル) EXCELの外部データ取得ができない 1 2023/03/23 09:03
- デスクトップパソコン 通話が遅延します 1 2023/06/18 02:36
- ガラケー・PHS SMSメールの受信遅延原因はガラケー自体の欠陥では 8 2022/08/06 11:46
- Outlook(アウトルック) OCN WEBメールについて 1 2022/05/18 23:33
- モニター・ディスプレイ 長文です。デスクトップPCのHDMI入力機能について 4 2022/09/20 17:58
- C言語・C++・C# TCP/IP通信時のサーバーからの受信 2 2022/11/23 09:11
- Wi-Fi・無線LAN 最近、WiFiの問題でPCがろくに使えないのですがどうすればいいですか。 現在、何らかの原因でPCを 5 2023/02/19 12:52
- ガラケー・PHS 携帯電話の居場所信号の発信タイミング 3 2022/07/27 14:39
- 中学校 娘のクラスの学級通信に個人情報が掲載されていて、非常に不快です。 7 2022/04/22 18:02
- C言語・C++・C# c言語の問題です 2 2023/07/21 10:51
このQ&Aを見た人はこんなQ&Aも見ています
-
【大喜利】【投稿~11/1】 存在しそうで存在しないモノマネ芸人の名前を教えてください
【お題】 ・存在しそうで存在しないモノマネ芸人の名前を教えてください
-
秘密基地、どこに作った?
小さい頃、1度は誰もが作ったであろう秘密基地。 大人の今だからこそ言える、あなたの秘密基地の場所を教えてください!
-
初めて自分の家と他人の家が違う、と意識した時
子供の頃、友達の家に行くと「なんか自分の家と匂いが違うな?」って思いませんでしたか?
-
プリン+醤油=ウニみたいな組み合わせメニューを教えて!
プリンと醤油を一緒に食べると「ウニ」の味がする! というような意外な組み合わせから、新しい味になる食べ物って色々ありますよね。 あなたがこれまでに試した「組み合わせメニュー」を教えてください。
-
好きな和訳タイトルを教えてください
洋書・洋画の素敵な和訳タイトルをたくさん知りたいです!【例】 『Wuthering Heights』→『嵐が丘』
-
シリアル通信の出力バッファと送信完了イベントについて
C言語・C++・C#
-
WriteFileで送信できたかの確認方法は?
C言語・C++・C#
-
画面を強制的に再描画させる方法
C言語・C++・C#
-
-
4
std::stringからLPCWSTR型への変換
C言語・C++・C#
-
5
CString から LPCTSTRの型に変換
C言語・C++・C#
-
6
シリアル通信の受信待ちについて
C言語・C++・C#
-
7
C# シリアル通信でデータ受信時の欠損について
C言語・C++・C#
-
8
WaitCommEventのタイムアウトについて
C言語・C++・C#
-
9
(マルチスレッド)_beginthreadexに複数の引数を渡す
C言語・C++・C#
-
10
CStringからchar*への型変換について教えてください。
C言語・C++・C#
-
11
FindFirstFileとFindNextFileで検索される順番
C言語・C++・C#
-
12
UpdateData( FALSE); による文字列データの表示更新(VC++6.0)
C言語・C++・C#
-
13
WaitForSingleObjectの使い方について
C言語・C++・C#
-
14
ソケット通信 同じポート番号でn対1はできない?
C言語・C++・C#
-
15
シリアル通信時のデータ受信方法
Visual Basic(VBA)
-
16
USB機器からのデータ受信による割り込み処理について
C言語・C++・C#
-
17
CStringのFindで文字列検索を行いたいのですが
C言語・C++・C#
-
18
「fatal error C1189」を回避するには?
C言語・C++・C#
-
19
エクセル VBA でのCOMポート認識
その他(プログラミング・Web制作)
-
20
CString型 全角半角を意識せずに「1文字」ずつ取り出す
C言語・C++・C#
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・プリン+醤油=ウニみたいな組み合わせメニューを教えて!
- ・タイムマシーンがあったら、過去と未来どちらに行く?
- ・遅刻の「言い訳」選手権
- ・【大喜利】【投稿~11/12】 急に朝起こしてきた母親に言われた一言とは?
- ・好きな和訳タイトルを教えてください
- ・うちのカレーにはこれが入ってる!って食材ありますか?
- ・好きな「お肉」は?
- ・あなたは何にトキメキますか?
- ・おすすめのモーニング・朝食メニューを教えて!
- ・「覚え間違い」を教えてください!
- ・とっておきの手土産を教えて
- ・「平成」を感じるもの
- ・秘密基地、どこに作った?
- ・【お題】NEW演歌
- ・カンパ〜イ!←最初の1杯目、なに頼む?
- ・一回も披露したことのない豆知識
- ・これ何て呼びますか
- ・初めて自分の家と他人の家が違う、と意識した時
- ・「これはヤバかったな」という遅刻エピソード
- ・これ何て呼びますか Part2
- ・許せない心理テスト
- ・この人頭いいなと思ったエピソード
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・ハマっている「お菓子」を教えて!
- ・【大喜利】【投稿~11/1】 存在しそうで存在しないモノマネ芸人の名前を教えてください
- ・好きなおでんの具材ドラフト会議しましょう
- ・餃子を食べるとき、何をつけますか?
- ・あなたの「必」の書き順を教えてください
- ・ギリギリ行けるお一人様のライン
- ・10代と話して驚いたこと
- ・つい集めてしまうものはなんですか?
- ・自分のセンスや笑いの好みに影響を受けた作品を教えて
- ・【お題】引っかけ問題(締め切り10月27日(日)23時)
- ・大人になっても苦手な食べ物、ありますか?
- ・14歳の自分に衝撃の事実を告げてください
- ・【大喜利】【投稿~10/21(月)】買ったばかりの自転車を分解してひと言
- ・ホテルを選ぶとき、これだけは譲れない条件TOP3は?
- ・家・車以外で、人生で一番奮発した買い物
- ・人生最悪の忘れ物
- ・【コナン30周年】嘘でしょ!?と思った○○周年を教えて【ハルヒ20周年】
- ・あなたの習慣について教えてください!!
- ・都道府県穴埋めゲーム
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C# シリアル通信でデータ受信...
-
バッファ領域がありません。と...
-
WriteFile()でのデータ送信がで...
-
mscommの受信バッファ異常について
-
Linuxでのシリアル通信について...
-
再現性の無いバグ
-
UDP処理のエラーについて
-
winsockでソケット通信の開発を...
-
ソケット通信内 read関数について
-
popen実行時にバッファが空の場合
-
exeファイルのセキュリティ。
-
Connection reset by peer
-
Macターミナルで実行中のプログ...
-
家電製品の電力周波数を変える機械
-
バックグラウンドのプロセスの...
-
C言語で、メモリを解放しないで...
-
他のアプリケーションをクリッ...
-
VBAの配列サイズとメモリに関して
-
VBSの処理中一旦処理を止めて再...
-
VBSで応答不要のメッセージボッ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
C# シリアル通信でデータ受信...
-
WriteFile()でのデータ送信がで...
-
UDP処理のエラーについて
-
シリアル通信の出力バッファと...
-
socket: recvはいつ,どれだけ...
-
winsockでソケット通信の開発を...
-
Linuxでのシリアル通信について...
-
SocketのSend関数でのCLOSEの検...
-
シリアル通信エラー
-
recv関数の受信結果について
-
ソケット通信内 read関数について
-
「スイッチングハブのバッファ...
-
ClearCommError呼び出し時のCE_...
-
シリアルポート通信
-
SerialPortのDataReceivedイベ...
-
WinsockAPIのrecvfromの受信デ...
-
Connection reset by peer
-
【CAsyncSocket::OnReceive()呼...
-
RS232C通信(PC⇔PLC)
-
0byteデータの送信と受信
おすすめ情報