🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C#

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

Q&A

解決済

3回答

2323閲覧

C# 送信サイズと受信サイズが異なる

whesty

総合スコア16

C#

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

0グッド

0クリップ

投稿2019/11/03 16:59

TCPで10MBの画像を送ったのですが受け取る側では850KB程度になってしまいます。
受信部分のbyte型からImage型への変換が原因かと思い、他の変換を試しましたがだめでした。
どなたかご教授願えると幸いです。
よろしくお願いします。

送信部分

C#

1 byte[] buf = ToByteArray(ImageSource); 2 byte[] tbuf = new byte[buf.Length + 1]; 3 tbuf[0] = (byte)'i'; 4 for (int i = 1; i < buf.Length + 1; i++) { 5 tbuf[i] = buf[i - 1]; 6 } 7 netStream.Write(tbuf, 0, tbuf.Length); 8 9///byte型に変換 10public byte[] ToByteArray(Image imageIn) 11 { 12 var ms = new MemoryStream(); 13 imageIn.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg); 14 return ms.ToArray(); 15 }

受信部分

C#

1 string str = ""; 2 byte[] buf = new byte[1024 * 1024 * 11]; 3 int len = s.Read(buf, 0, buf.Length); 4 while (len > 0) { 5 var tbuf = new byte[buf.Length - 1]; 6 for (int i = 0; i < buf.Length - 1; i++) { 7 tbuf[i] = buf[i + 1]; 8 } 9 if (buf[0] == (byte)'i') 10 { 11 var img = ToImage(tbuf); 12 var e = new MessageEventArgs(); 13 e.Type = MessageType.Image; 14 e.Image = img; 15 e.Message = null; 16 e.IPAddress = ipa; 17 ReceivedMessageHandler(e); 18 } 19    else if (buf[0] == (byte)'m') { 20  str = Encoding.UTF8.GetString(tbuf, 0, len - 1); 21 var e = new MessageEventArgs(); 22 e.Type = MessageType.Message; 23 e.Image = null; 24 e.Message = str; 25 e.IPAddress = ipa; 26 ReceivedMessageHandler(e); 27 } 28 len = s.Read(buf, 0, buf.Length); 29 } 30///Imageへ変換 31public static Image ToImage(byte[] byteArrayIn) 32 { 33 var ms = new MemoryStream(byteArrayIn); 34 var returnImage = Image.FromStream(ms); 35 return returnImage; 36 }

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

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

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

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

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

guest

回答3

0

VisualStudioを使ってるなら、受信ループのところで実行を止め、どういう動作をしてるのかを追いかけていってはどうでしょう
そうすれば少なくとも、わけわからずにダメ、ってことにはなりません。

こういう通信のコードではよくあることですが、10M送ったからといって受信も10Mそのまま来たりはしません。
たとえば1Kバイトづつ来たりとか細切れに来るのでそこらへんで破綻してるものと思われます

投稿2019/11/03 21:52

y_waiwai

総合スコア88038

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

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

0

ベストアンサー

ソケット通信による送受信はsendとrecvの関数呼び出しが1対1になるとは限りません。
というか、ならない前提でコーディングしてください。

たとえば簡易的な仕様ですが、

●送信側
・先頭に4バイト分バイナリサイズを付加して送信する
([画像サイズ4byte][画像データ....]的な。)
※C#のTCPクラスの挙動忘れましたが、一応ちゃんと送信出来たか送信バイト数のチェックもやった方がいいです。

●受信側
・まず4バイト分を受信するまで受信処理をループさせる(ループでブロックして良いかは要確認)
・↑に必要なバイト数が書かれていますので、そのバイト数分のデータを すべて 受信するまで受信処理を続ける(ループでブロックして良いかは要確認)
・受信し終わったら画像をデコードする

といった事をやれば期待した結果は得られると思います。
4バイトで扱えないサイズだったらどうするかとかは適当に考えてください。

投稿2019/11/05 07:57

編集2019/11/05 07:58
takabosoft

総合スコア8356

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

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

0

受信ループの途中で画像を作ってるからじゃないでしょうか。

投稿2019/11/03 21:25

Zuishin

総合スコア28669

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問