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

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

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

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

UDP

UDP(User Datagram Protocol)とは、トランスポート層のプロトコルであり、コネクション型のデータサービスです。IPネットワーク上の別のホストにコンピュータのアプリケーションがメッセージを送ることができ、転送チャンネルやデータ経路を設定する必要はありません。TCPに比べて高速であるが、信頼性が薄いという特徴があります。

ネットワーク

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

Q&A

解決済

1回答

7798閲覧

画像をUDPで送りそれを受信する側でフォームに貼り付けるプログラムについて

kiritsugu

総合スコア127

C#

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

UDP

UDP(User Datagram Protocol)とは、トランスポート層のプロトコルであり、コネクション型のデータサービスです。IPネットワーク上の別のホストにコンピュータのアプリケーションがメッセージを送ることができ、転送チャンネルやデータ経路を設定する必要はありません。TCPに比べて高速であるが、信頼性が薄いという特徴があります。

ネットワーク

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

0グッド

0クリップ

投稿2017/01/23 12:53

現在質問タイトルのようなプログラムを作っていて一応は動くようになったのですが、理想していたものとはかけ離れた状態に困惑しています。
完成イメージはマウスの動きを認識できるくらいスムーズに画像を変えていきたかったのですが、それ以前に一枚目もロクに表示できずかろうじて画面の上部分1/5くらいがフォームに表示される程度でした。
そして非常に重いです。これでは今後考えている機能追加にも困ります。ネットワークのプログラムを書くのは初めてなのですが、なぜこんなに重くなるのでしょうか。
またスムーズに画像を変えていくにはどんな風にプログラムを改変すればよいのか教えてください。

画像を撮って送るほうのプログラム

c#

1using System; 2using System.Collections.Generic; 3using System.ComponentModel; 4using System.Data; 5using System.Drawing; 6using System.Linq; 7using System.Text; 8using System.Threading.Tasks; 9using System.Windows.Forms; 10using System.Net; 11using System.Net.Sockets; 12using System.IO; 13 14namespace ControlServer 15{ 16 public partial class Form1 : Form 17 { 18 public Form1() 19 { 20 InitializeComponent(); 21 this.SendImage(); 22 } 23 24 public async void SendImage() 25 { 26 while (true) 27 { 28 int cnt = 0; 29 List<byte> bytelist = new List<byte>(); 30 IPEndPoint remote = new IPEndPoint(IPAddress.Parse("192.168.1.59"), 8000); 31 byte[] imgbyte = ScreenCapture.CaptureBitmap(); 32 await Task.Delay(1000); 33 34 Back : for (; cnt < imgbyte.Length; cnt++) 35 { 36 try { 37 if (imgbyte.Length - cnt < 1300) 38 { 39 using (var client = new UdpClient(8001)) 40 { 41 client.Connect(remote); 42 byte[] remain = imgbyte.Skip(cnt).Take(imgbyte.Length - cnt).ToArray(); 43 await client.SendAsync(remain, remain.Length); 44 } 45 using (var client = new UdpClient(8001)) 46 { 47 client.Connect(remote); 48 byte[] end = Encoding.UTF8.GetBytes("end"); 49 await client.SendAsync(end, end.Length); 50 } 51 break; 52 } 53 54 if (bytelist.Count == 1300) 55 { 56 using (var client = new UdpClient(8001)) 57 { 58 client.Connect(remote); 59 await client.SendAsync(bytelist.ToArray(), bytelist.ToArray().Length); 60 } 61 bytelist = new List<byte>(); 62 await Task.Delay(10); 63 } 64 else 65 { 66 bytelist.Add(imgbyte[cnt]); 67 } 68 } 69 catch(Exception) 70 { 71 MessageBox.Show("エラー"); 72 goto Back; 73 } 74 } 75 } 76 } 77 } 78 79 // 画面をとりbyte配列にして返す 80 static class ScreenCapture 81 { 82 public static byte[] CaptureBitmap() 83 { 84 byte[] byteimage; 85 Bitmap bm = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height); 86 87 using (var mms = new MemoryStream()) 88 { 89 using (var graphics = Graphics.FromImage(bm)) 90 { 91 graphics.CopyFromScreen(new Point(0, 0), new Point(0, 0), bm.Size); 92 bm.Save(mms, System.Drawing.Imaging.ImageFormat.Jpeg); 93 byteimage = mms.GetBuffer(); 94 } 95 96 mms.Close(); 97 } 98 99 return byteimage; 100 } 101 } 102} 103

受け取ってフォームに表示するプログラム

C#

1using System; 2using System.Collections.Generic; 3using System.ComponentModel; 4using System.Data; 5using System.Drawing; 6using System.Linq; 7using System.Net; 8using System.Net.Sockets; 9using System.Text; 10using System.Threading.Tasks; 11using System.Windows.Forms; 12 13namespace ControlClient 14{ 15 public partial class Form1 : Form 16 { 17 private List<byte[]> ImageConnect { get; set; } = new List<byte[]>(); 18 19 public Form1() 20 { 21 InitializeComponent(); 22 this.ListenMessage(); 23 } 24 25 public async void ListenMessage() 26 { 27 var local = new IPEndPoint(IPAddress.Any, 8000); 28 var remote = new IPEndPoint(IPAddress.Any, 8000); 29 var client = new UdpClient(local); 30 31 while (true) 32 { 33 var recieve = await client.ReceiveAsync(); 34 byte[] result = recieve.Buffer; 35 36 if (Encoding.UTF8.GetString(result) == "end") // endが送られてきたらbyte配列を全部送ったことに 37 { 38 byte[] linking = null; 39 40 for(int i=0; i<this.ImageConnect.Count; i++) // List<byte[]>を1つのbyte[]でつなぎ合わせる 41 { 42 if(i == 0) 43 { 44 linking = Enumerable.Concat(this.ImageConnect[0], this.ImageConnect[1]).ToArray(); 45 } 46 else 47 { 48 if (i + 1 > this.ImageConnect.Count-1) break; 49 linking = Enumerable.Concat(linking, this.ImageConnect[i + 1]).ToArray(); 50 } 51 } 52 ImageConverter imgconv = new ImageConverter(); 53 Image img = (Image)imgconv.ConvertFrom(linking); // byte配列をImageオブジェクトへ 54 this.OnRecieve(img); 55 this.ImageConnect = new List<byte[]>(); 56 } 57 else 58 { 59 this.ImageConnect.Add(result); 60 } 61 } 62 } 63 64 private void OnRecieve(Image img) // フォームのバックグラウンドイメージに 65 { 66 this.Width = img.Width + 5; 67 this.Height = img.Height + 20; 68 this.BackgroundImage = img; 69 } 70 } 71} 72

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

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

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

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

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

guest

回答1

0

ベストアンサー

まずは、データは圧縮しましょう。
次に各処理の時間を測って見ましょう。
ImageConnectはListよりも効率の良いものにしましょう。
毎回全フレームを送るのではなく、変化があった領域だけ送りましょう、

と言ってもまだまだ足りないので、、、
以下のコンポーネントなどの活用を考えましょう。

http://devlights.hatenablog.com/entry/20091120/p1

ところで、ループ処理も例えば以下のように改善が必要です。

for (; cnt < imgbyte.Length; 4096 )
{
sendsize = min( 4096, imagebyte.Length-cnt );
Array.Copy(imagebyte, cnt, sendBuffer, 0, sendsize);
cnt += sendsize;

sendBufferを送る
}
endを送る

udpを使う場合はデータの到達順序やデータが消えることなども考慮が必要です。画像を一枚送るだけでもそこそこコツが必要です、TCPを使った方が良いですね。

投稿2017/01/23 22:41

編集2017/01/24 00:06
hikochang

総合スコア648

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

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

kiritsugu

2017/01/25 15:54

tcpで上記のことを実践してみようと思います。ありごとうございました
hikochang

2017/01/25 16:14

TCPすることで、遅くても画像は表示されるようになると思いますのでまずはそこを目指しましょう。 高速化については、転送量を少なくすることを考えましょう。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問