質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

TCP

TCP(Transmission Control Protocol)とは、トランスポート層のプロトコルで、コネクション型のデータサービスです。

.NET Framework

.NET Framework は、Microsoft Windowsのオペレーティングシステムのために開発されたソフトウェア開発環境/実行環境です。多くのプログラミング言語をサポートしています。

ネットワーク

ネットワークとは、複数のコンピューター間を接続する技術です。インターネットが最も主流なネットワークの形態で、TCP/IP・HTTP・DNSなどの様々なプロトコルや、ルータやサーバーなどの様々な機器の上に成り立っています。

Q&A

解決済

2回答

3681閲覧

BinaryReader.ReadBytes(Int32) の挙動について

castanopsia

総合スコア12

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

TCP

TCP(Transmission Control Protocol)とは、トランスポート層のプロトコルで、コネクション型のデータサービスです。

.NET Framework

.NET Framework は、Microsoft Windowsのオペレーティングシステムのために開発されたソフトウェア開発環境/実行環境です。多くのプログラミング言語をサポートしています。

ネットワーク

ネットワークとは、複数のコンピューター間を接続する技術です。インターネットが最も主流なネットワークの形態で、TCP/IP・HTTP・DNSなどの様々なプロトコルや、ルータやサーバーなどの様々な機器の上に成り立っています。

0グッド

0クリップ

投稿2020/02/05 09:59

NetworkStreamからTCP受信データを読み取る際、受信途中であった場合、掲題のBinaryReader.ReadBytesメソッドは処理をブロックしますか?

C#

1var listener = TcpListener(selfHostName, receivePort); 2listener.Start(); 3try 4{ 5 using (var sender = listener.AcceptTcpClient()) 6 using (var receivedStream = sender.GetStream()) 7 using (var reader = new BinaryReader(receivedStream)) 8 { 9 // ここで 10byte のデータが送られてくる想定。 10 // もしここの処理に入った瞬間にまだ 10byte 未満(4byteとか)しか送られてきていない(送信途中)の場合、 11 // 10byte 目が送られてくるまでブロックされますか? 12 var readData = reader.ReadBytes(10); 13 } 14} 15finally 16{ 17 listener.Stop(); 18}

よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

BinaryReader.ReadBytesメソッドは処理をブロックしますか?

はい。ご提示のコードにて、BinaryReaderで生成したリーダーオブジェクトを使う場合は、指定長分のデータを取り込むまでブロックします。つまりReadBytes(10)での呼び出しは10バイト取り出すまで、ReadInt16()の呼び出しは2バイト取り出すまでブロックします。

尚、BinaryReaderを使わずにsender.GetStream()で生成したNetworkStreamReadを使うのであれば、ブロックしません。(それを踏まえてのご質問だったのかもしれませんが、参考まで)

C#

1using (var receivedStream = sender.GetStream()) 2{ 3 // ブロックせず、受信した分だけ取り出してすぐ戻る。 4 Console.WriteLine("start."); 5 byte[] bytes = new byte[256]; 6 int receivedLen = receivedStream.Read(bytes, 0, bytes.Length); 7 Debug.WriteLine($"len={receivedLen}"); 8 string s = BitConverter.ToString(bytes, 0, receivedLen); 9 Debug.WriteLine(s); 10}

投稿2020/02/05 13:34

dodox86

総合スコア9256

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

ブロックしません。
その時点に読み込まれたデータを返します

投稿2020/02/05 10:31

y_waiwai

総合スコア88042

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

castanopsia

2020/02/05 10:34

なるほど ちなみに BinaryReader.ReadInt16() 等も同様でしょうか?
y_waiwai

2020/02/05 10:37

ストリームの末尾に到達したら例外でますね
castanopsia

2020/02/05 10:46

わかりました。回答ありがとうございました。
Zuishin

2020/02/05 11:27

あと、末尾に到達してさらに読み込もうとした場合(クローズされてない時)、どのような例外が出ますか?
y_waiwai

2020/02/05 11:35

例外 EndOfStreamException ストリームの末尾に到達しました。 とのことですねー
Zuishin

2020/02/05 11:41

疑問形なのは、私が今それを確かめられる環境にいないからです。しかし、非常に疑わしいと思っています。
y_waiwai

2020/02/05 11:51

ReadBytesでは空配列が帰るので、そんで判別できるって話なのでは。
Zuishin

2020/02/05 11:53

では例外は出ないのでは?
Zuishin

2020/02/05 11:59 編集

そしてたまたままだデータが届いていないときにも空配列が戻るということは、ブロックされないのなら判別できないのでは?
y_waiwai

2020/02/05 11:55

ReadBytes ではEndOfStreamExceptionはでないんでしょうね
Zuishin

2020/02/05 12:00

ReadBytes の話をしています。質問にもそう書いてあります。本当にこの回答が正しいか、一度確かめてもらえませんか?
y_waiwai

2020/02/05 12:04

castanopsia 2020/02/05 19:34 なるほど ちなみに BinaryReader.ReadInt16() 等も同様でしょうか? y_waiwai 2020/02/05 19:37 ストリームの末尾に到達したら例外でますね という経緯ですね
Zuishin

2020/02/05 12:06

同様ではないと思いましたので、確かめてください。
dodox86

2020/02/05 12:46

私も??と思ったので、確認しました。少なくとも質問者さんのコードではTCPのコネクションが生きている限り指定長を受信するまでReadBytes(10)は10バイト、ReadInt16は2バイト受信するまでブロックします。GetStream()やBinaryReader()が絡んでいるせいかもしれませんが。
dodox86

2020/02/05 12:49

ストリームの末端の検出は、TCPコネクションが切れたとき、です。指定長の受信を待たず、System.IO.EndOfStreamException例外が発生します。
Zuishin

2020/02/05 12:59

dodox86 さんありがとうございました。安心して眠れます。
y_waiwai

2020/02/05 13:04

そういうことなら回答に書いてあげてください
dodox86

2020/02/05 13:41

私のコメントで語弊がある表現がありましたので訂正させていただきます。 > 指定長を受信するまでReadBytes(10)は10バイト、ReadInt16は2バイト受信するまでブロックします。 受信するまで、と言うより「TCP上はデータは受信できているのだけれども、BinaryReaderを介する場合は、指定長分取り出せるようになるまでブロック」が正しいようです。で、回答させていただきました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問