
Visualstudio 2013 を使用して C# で開発を行っています。
Socket Classを使用してデータの送受信をするプログラムを作成しているのですが、
非同期でデータを受信する際に取りこぼしなくデータを受信させる方法で悩んでいます。
現在行っているのは、
socket.BeginReceiveでデータ受信時のコールバック関数を登録し受信開始。
データ受信時のコールバック関数の中で
len = socket.EndReceive(ar);
byte[] rcvBuff = (byte[])ar.AsyncState;
でデータとサイズを取得
再度socket.BeginReceiveで受信開始。
としています。
悩んでいるのは EndReceive から、二回目のBeginReceiveまでの間に送られたデータを取りこぼしてしまうのではないかということです。
認識として間違っていたら指摘頂きたいです。
また、別の方法で非同期で取りこぼしなく受信できるやり方が有りましたらヒントでもよいので教えていただけたらと思います。
よろしくお願いします。
No.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さんだってそんなコンポーネント作らんじゃろ。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
-
教えて!gooグレードポイントがdポイントに変わります!
dアカウント連携を行っていただくと、グレードに応じて「dポイント」が進呈されるようになります。
-
C# シリアル通信でデータ受信時の欠損について
C言語・C++・C#
-
UDP通信する時に、相手にどうやって自分のポート番号を教える?
Java
-
NetworkStreamからのRead()で、処理が止まる(C#)
C言語・C++・C#
-
4
UdpClient 送信元のIPアドレスの指定方法
C言語・C++・C#
-
5
C#で通信処理。応答がない場合、すぐエラーにしたい
その他(プログラミング・Web制作)
-
6
Linuxでのシリアル通信についてですが、受信のときにデータがずれた状態で送られてくることがあります
C言語・C++・C#
-
7
c# 文字列の最後から1文字削除したい
C言語・C++・C#
-
8
高速シリアル通信での大容量のデータ転送について(mscomm)
Visual Basic(VBA)
-
9
変数名の付け方
Java
-
10
C#にて別クラスの関数を使いたい
C言語・C++・C#
-
11
フルパスから最後のディレクトリ名を取得したい。
Visual Basic(VBA)
-
12
UDP受信時の通信異常検知について
C言語・C++・C#
-
13
ネットワーク切断を検出するには?
C言語・C++・C#
-
14
指定されたサービスは削除の対象としてマークされています。
Windows Vista・XP
-
15
C#で設定時刻到来時にイベントを発生させたい
C言語・C++・C#
-
16
CloseとDisposeの違い
Visual Basic(VBA)
-
17
シリアル通信でのデータ取りこぼし
Visual Basic(VBA)
-
18
ビットの取り出し方法
C言語・C++・C#
-
19
UDP処理のエラーについて
Visual Basic(VBA)
-
20
DataGrdViewに関連付けたデータの更新
C言語・C++・C#
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
人気Q&Aランキング
-
4
教えて下さい
-
5
ACCESS VBA インデックスが有効...
-
6
ブレーカー落ちで壊れたりしな...
-
7
エクセルで2つの時系列のデー...
-
8
多量のSUMIF式を軽くしたい
-
9
ウィンドウ枠の固定を行の2箇所...
-
10
ExcelVBAでデータ不一致のもの...
-
11
VBにおいてフォーム間の変数の...
-
12
シーケンサにパソコンからアク...
-
13
ACCESSからEXCELに出力する際、...
-
14
C# ソケット通信でデータ受信時...
-
15
配列でデータが入っている要素...
-
16
ビットシフトについて
-
17
VBA 該当データがない時 ...
-
18
excel vba 検索ボタン作成について
-
19
リングバッファって何ですか
-
20
Rを使った、はずれ値の自動除去...
おすすめ情報
公式facebook
公式twitter