プログラミングをしていて詰まったところがあるので教えていただけると幸いです。
開発環境は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で質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
-
都道府県穴埋めゲーム
都道府県の名前を1人1つずつ投稿してください。全ての都道府県が出たら締め切ります!
-
フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
あなたが普段思っている「これまだ誰も言ってなかったけど共感されるだろうな」というあるあるを教えてください
-
映画のエンドロール観る派?観ない派?
映画が終わった後、すぐに席を立って帰る方もちらほら見かけます。皆さんはエンドロールの最後まで観ていきますか?
-
海外旅行から帰ってきたら、まず何を食べる?
帰国して1番食べたくなるもの、食べたくなるだろうなと思うもの、皆さんはありますか?
-
天使と悪魔選手権
悪魔がこんなささやきをしていたら、天使のあなたはなんと言って止めますか?
-
シリアル通信プログラム(受信)について
C言語・C++・C#
-
C# シリアル通信でデータ受信時の欠損について
C言語・C++・C#
-
シリアル通信でのデータ受信
C言語・C++・C#
-
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・人生のプチ美学を教えてください!!
- ・10秒目をつむったら…
- ・あなたの習慣について教えてください!!
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・【大喜利】【投稿~9/18】 おとぎ話『桃太郎』の知られざるエピソード
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
Ruby1.8を使って、パケット...
-
パケットキャプチャについて
-
ワード ある日突然 文書の表...
-
wordの文書をPC画面中央に表示...
-
結局、ノートパソコンはいつ買...
-
2台のPCでRS-232C接続でファイ...
-
外部のPC(たとえば学校)から...
-
エクセルの列と行の見出しが小...
-
社内ネットワークで、ログアウ...
-
勝手にファイルが消えたり移動...
-
Microsoft office 2010
-
パソコン使える人はカッコイイ...
-
クリープを入れないコーヒーな...
-
av4と言うエ○サイトって動画を...
-
WebサーバとFTPサーバってどう...
-
勝手にフォルダやファイルが開...
-
フリーダイヤル
-
ウェブサーバの統計で、リクエ...
-
何で元のファイルとアップロー...
-
CISCO上でtftp操作
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
高速シリアル通信での大容量の...
-
Winsock 受信について
-
シリアル通信でのデータ分け
-
HTTP POST送信のヘッダの書き方
-
パリティビットはわかるけど、...
-
TCP/IP通信3ハンドシェイクにつ...
-
同期速度とは
-
UDPでマルチスレッドは可能か
-
UDPのデータ転送について
-
リピータHUBでコリジョンが認識...
-
データ通信にかかるパケットに...
-
パケットのフィルタリング
-
auを使っていますーーーー デー...
-
ドコモでのIphone5Cでのテザリ...
-
パケットキャプチャについて
-
UDPの送信確認
-
ローカルプロキシの作り方を教...
-
配列内に通番(文字列)を挿入し...
-
セル、データグラム、パケット...
-
通信量の違い(ストリーミングと...
おすすめ情報