dポイントプレゼントキャンペーン実施中!

Visualstudio 2013 を使用して C# で開発を行っています。

Socket Classを使用してデータの送受信をするプログラムを作成しているのですが、
非同期でデータを受信する際に取りこぼしなくデータを受信させる方法で悩んでいます。

現在行っているのは、
 socket.BeginReceiveでデータ受信時のコールバック関数を登録し受信開始。

 データ受信時のコールバック関数の中で
 len = socket.EndReceive(ar);
 byte[] rcvBuff = (byte[])ar.AsyncState;
 でデータとサイズを取得

 再度socket.BeginReceiveで受信開始。

としています。

悩んでいるのは EndReceive から、二回目のBeginReceiveまでの間に送られたデータを取りこぼしてしまうのではないかということです。


認識として間違っていたら指摘頂きたいです。
また、別の方法で非同期で取りこぼしなく受信できるやり方が有りましたらヒントでもよいので教えていただけたらと思います。

よろしくお願いします。

A 回答 (1件)

> 悩んでいるのは EndReceive から、


> 二回目のBeginReceiveまでの間に送られたデータを取りこぼしてしまうのではないかということです。
大丈夫よん。

プログラムがBeginReceive~EndReceiveでひとかたまりの受信データブロックを取得するのはあくまで「同じコンピューターのOSから」なので、その時「同じコンピューターのOS」は相手からのデータ送信をどんどこどんどこ受け付けている。
そもそも最初のBeginReceiveをしなくてもコネクションが確立された瞬間からOSは相手からデータを受け取っているのだ。

これは、次のようなイメージだ。
(1)あなたは一階に総合受付がある雑居ビルで仕事をしてる。(あなた=プログラム、総合受付=NIC)
(2)一階の総合受付の中にあなた宛の郵便受けを置いたとする。(Socket#Listen、Socket#Accept)
(3)郵便屋さんはそこにあなた宛の郵便をどんどこどんどこ持ってくる。
(4)あなたは部下に「郵便受けに何かないか見てこい。何もなかったら何か来るまでそこで見張ってろ。郵便が有ったら報告せよ。」という。(BeginReceive)
(5)部下は降りていった時に郵便があればそのまま持って上がる。無ければ来るまで待つ。(コールバック)
(6)あなたは部下から郵便を受け取って再び(4)を命じる。(EndReceive、AsyncState、BeginReceive)

ここで、(3)と(4)~(6)は非同期にかつ独立して行われる。あなたや部下が郵便を取りに行こうが取りにいくまいが郵便屋さんは郵便を持ってきて便受けに入れるだけだ。具体的には(6)でEndReceiveとBegenReceiveの間に郵便屋さんが来たとしてもそれは便受けに郵便を入れるだけだ。
もちろん、あなたのプログラムが終了しようとしている時に郵便受けに溜まってるのにあなたが読まなかった郵便はプログラム終了(というかSocket#Close)とともにロストする。
TCPはこの郵便受けがぱんぱんになってしまったら郵便屋さん(というか郵便を送りつけてくる相手)にちょっと待って貰うとかそういう制御もしている。

イメージ的にはこんなイメージであなたはBeginReceiveとEndReceiveを実行するタイミングによる伝送データロストを気にする必要はない。もし本当にそんなちょっとしたタイミングの差でそんな事が起こるんならMicrosoftさんだってそんなコンポーネント作らんじゃろ。
    • good
    • 0
この回答へのお礼

ありがとうございます。
そのままでよさそうですね。
わかりやすいたとえで理解出来ました。

お礼日時:2014/09/01 13:29

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています