
プログラミングをしていて詰まったところがあるので教えていただけると幸いです。
開発環境はWindows XPでVisual C++ 2005 です。
シリアル通信において次々と送られてくるデータを1データずつ間違いがないように受信することを考えます。
例えば1つのデータが10バイトからなっていて、そのはじめが
0x10というものだったとすれば、
0x10を検出し、その10個分先の0x10の1つ前までが1データ分となると思います。
これを繰り返して全てのデータを正しく取得したいのですが、プログラムの方法が思い浮かびません。
こんなプログラムの方法はどうか、こんな関数を使ってみてはどうか、などありましたらご教授下さい。
よろしくお願いいたします。
No.3ベストアンサー
- 回答日時:
シリアル通信(データ通信)で避けて通れないのが「同期」と「パケット化」と「エラー判定」と「プロトコルの設計」です。
同期(キャラクタ同期)については、通常、ハードウェアで行うので、ソフトは余り気にしなくて良いのですが、同期ズレは発生した場合、幾つかのバイトが欠落するのをソフト側で考慮しなければなりません。
パケット化は、例えば、データの先頭にマーカー、レングス、連番などを入れ、末尾にチェックサムやCRCを入れるなど、自分でデータ構造を構築しなければなりません。
エラー判定は、パケット単位でデータのチェックサムやCRCを入れ、受け取ったパケットが正常であるか判定しなければなりません。
プロトコルの設計は、データの送受信の双方で、データのやりとりの方法を決め、色々な事象(データ抜け、データ化け、エラー、再送など)に対応した設計をしないとなりません。
質問者さんが考えたように「先頭にレングスだけ」では、もし「先頭のレングスが文字化けした時」や「途中のデータが化けた時」や「途中のデータが抜け落ちた時」に、正しくデータが受信できません。
例えば、以下のような15バイトを、10+5バイトで送出する場合を考えます。
送出データは以下のようになります。
(0A) 01 02 03 04 05 06 07 08 09 10 (05) 11 12 13 14 15
注:()内はレングス
ここで、以下のように先頭が文字化けすると
(08) 01 02 03 04 05 06 07 08 09 10 (05) 11 12 13 14 15
受信側は
(08) 01 02 03 04 05 06 07 08 (09) 10 05 11 12 13 14 15
と解釈し、まず8バイト受け取り、次に9バイト取ろうとしますが、データはいつまで経っても9バイト来ません。永久に待つ事になります。
もし、10が来るまで読み捨ててると、
(08) 01 02 03 04 05 06 07 08 (09)
を捨てて、その先の
(10) 05 11 12 13 14 15
を受け取ろうとしますが、やはり、データは10バイト来ません。永久に待つ事になります。
もし、以下のようにデータの中身が文字化けしたら
(10) 01 12 03 04 05 06 07 08 09 10 (05) 11 12 13 14 15
受信側は02が12に化けたのに気付く事ができません。
なので、パケットの中は「どこが欠落しても、どこが文字化けしても、それが判るようにする必要」があります。
そして「受信パケットがエラーか正常か判定可能」になったら、受信側から送信側に「正常だから次を送れ」とか「エラーだからもう1回送って」などの返答を返す必要が出てきます。
この「受信したらどういう返事をどう返すのかの、取り決め」のが「プロトコル」です。
パケットの設計、エラー判定の設計、プロトコルの設計が出来て、初めて「間違いの起きない送受信」が可能です。
こういうシリアル通信の送受信プロトコルは、既に色々な物が作られているので、そういう資料を見てみるのが良いでしょう。
No.5
- 回答日時:
追記。
実は「LANによるネットワーク通信」も、中身はシリアル通信と同じで、データ抜けやデータ化けが起きています(コリジョンや回線不良)
で、パケット化、エラー訂正は、NIC(ネットワークインターフェースカード)に載っているコントローラLSIが勝手にやってくれます。
あとは、サーバー、クライアントで「プロトコル」を決め、FTPやHTTPやSMTPやPOP3などのサーバーソフト、クライアントソフトが、決められたプロトコル通りにデータを送受信しています。
ですので「確実なシリアル通信の手順」を一から書くのは、ネットワーク階層構造のデータリンク層から上を自分で書くのと同じです(NICのコントローラLSIがやってる様なこと、サーバーソフト、クライアントソフトがやってる様なことを、全部、一から自分で書く、ということ)
No.4
- 回答日時:
> やり方が色々あり、人によって全然違うプログラムになるということ、とかいうことでしょうか?
逆です。
誰がやっても、同じようなプログラムになるうえに、簡単に書けてしまうのでライブラリが用意されていない。
「1から10までの合計を計算して表示しなさい」というプログラムは、いかにも誰でも一度ぐらいは作っていそうですが、これを簡単に実行する関数やライブラリはわざわざ用意されたりしていませんし、仮にあったとしても、わざわざ使ったりしません。どういう言語であれ、おそらくはループ変数を使って足し算していき、最後に出力、という方法になるしかないでしょう。(再帰でもかける、とか、そういう突っ込みはなしです)
今回のご質問もこれと同じです。「とりあえず」であれば、素直にプログラムすればいいだけですから、悩みどころがないのです。
もちろん、実用的なプログラムであればエラー制御などは必須ですし、通信プログラムであれば相手がハングアップやリスタートした時の制御も必要ですから、どんどん複雑になります。が、やはりエラー制御やタイムアウトはライブラリにはなじまないので、自分で作るしかありません。でも、今回はそういう深いレベルの話ではないように思います。
No.2
- 回答日時:
> こんなプログラムの方法はどうか、こんな関数を使ってみてはどうか、などありましたら
ないでしょう。
画期的な関数も思いだしませんし、定番のプログラム方法もないと思います。
というか、「シリアル通信で」という部分をのぞけば、これって、ごく普通のプログラムですよね。こういう形式のファイルはたくさんありますし、そもそも、マシン語ってまさにこれだと思います。ある番地を指定されるとそこから「ひとかたまりの命令」を読み込んで実行し、その次の番地からまたまた「ひとかたまりの命令」を読み込む。「ひとかたまり」の判断は自分で行なうしかない。
それぐらい基本中の基本といってもいいプログラムだと思いますよ。人に質問する前にもっと自分で考えましょう。
回答ありがとうございます。
やはりそんなに都合の良いものはありませんか。
正直、実戦的な知識がほとんどない状態で放り込まれたようなものでして、どこに目をつけていいかもよく分からず途方にくれた状態です。
もちろん自分でも考えましたし、調べてもみたのですが・・・
基本中の基本のプログラムでありながら定番のプログラム方法がないとはどういうことでしょうか?
やり方が色々あり、人によって全然違うプログラムになるということ、とかいうことでしょうか?
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# C言語プログラム変更 2 2022/12/21 15:03
- HTML・CSS GETをPOSTに変更したところ 送信 不能です。 1 2022/04/10 17:31
- その他(プログラミング・Web制作) 大学のゼミのレポートがムカつきます。 R言語というデータ分析に特化したプログラム言語を用いた授業の課 1 2023/06/29 00:50
- デスクトップパソコン ウイルスに感染しないファイルのバックアップ方法について 5 2022/09/11 11:27
- Word(ワード) Wordのデータが毎回破損してしまう 1 2022/08/24 11:30
- C言語・C++・C# [C言語] コメント文字列を無視して、数値データを読み込むプログラム部分について 5 2022/10/05 11:03
- HTML・CSS WEBサイトの構築。表示データとWEBデザインを分離する考え方を専門用語・業界用語では何と言うか? 8 2022/09/27 09:16
- Android(アンドロイド) Androidスマホのデータ移行が終わらない 1 2023/08/04 17:25
- ドライブ・ストレージ 古い外付けHDDから新品外付けHDDへのデータ移行方法 (Mac) 2 2022/12/11 02:01
- Excel(エクセル) VBAで重複データを合算したい(時間) 1 2022/12/08 23:06
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
TCP/IPのデータ送受信の"確実性...
-
スマホでauなどの大手キャリア...
-
ワード ある日突然 文書の表...
-
wordの文書をPC画面中央に表示...
-
パソコンって家電製品だと思い...
-
File Savr - Free File Hosting...
-
CISCO上でtftp操作
-
FTPソフト filezillaのキューフ...
-
エクセルの列と行の見出しが小...
-
フリーダイヤル
-
av4と言うエ○サイトって動画を...
-
iPhoneでav4と言うエ○サイトの...
-
ポートアイソレートの意味
-
ノートパソコンでzoomを使って...
-
一本道の動画をパソコンで保存...
-
ネットワーク上のコンピュータ...
-
勝手にファイルが消えたり移動...
-
このソフト(.exe)が安全かど...
-
一時的に使える無料のレンタル...
-
ラジオ聴く時何してる?何をし...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
UDPでマルチスレッドは可能か
-
UDPの送信確認
-
リピータHUBでコリジョンが認識...
-
シリアル通信でのデータ分け
-
パリティビットはわかるけど、...
-
Winsock 受信について
-
ローカルプロキシの作り方を教...
-
ペイロードって何ですか?
-
パケットのフィルタリング
-
高速シリアル通信での大容量の...
-
同期速度とは
-
パケットキャプチャについて
-
TCP/IPのデータ送受信の"確実性...
-
ドコモでのIphone5Cでのテザリ...
-
ワード ある日突然 文書の表...
-
wordの文書をPC画面中央に表示...
-
2台のPCでRS-232C接続でファイ...
-
結局、ノートパソコンはいつ買...
-
FTPソフト filezillaのキューフ...
-
パソコンって家電製品だと思い...
おすすめ情報