问题:
1;为什么选用UDP而非TCP?
TCP,UDP是运输层两种重要的通信协议,向上层的应用层提供通信服务,同时也向下屏蔽了网络通信的细节。
TCP较为复杂,是面向有连接的、可靠的运输层通信协议,有确认机制;这一定程度上限制了该协议对于数据传输速度。
UDP面向无连接,面向报文的,是尽最大努力交付的不可靠通信协议,没有拥塞控制,即网络发生拥塞时不会是主机的发送速率降低,
这对于实时性要求比较高的如,视频会议、IP电话是比较合适的。
对于要传递的视频,我们更在乎他的实时性,因而UDP较为合适;但是个人觉得随着技术的发展,网络传输速率及可靠性的提高,TCP也是可以的。
如果你是在一个状况较好的局域网通信,不妨也可以试一下TCP,应该也不会出山么问题,个人觉得。
2;怎么组建基于运输层协议为UDP的局域网?
step1:实例化UDP端节点
IPEndPoint Ipe = new IPEndPoint(IPAdress,Port); //实例化本地IPEndPoint,并通过构造函数进行初始化 UdpClient client = new UdpClient(Ipe); //实例化UdpClient,并通过构造函数初始化;注:此过程也叫UDP客户端绑定端口
step2:数据准备
BitMap bitmap = photoPanel1.GetCurrentImage(); //从photoPanel获取一帧数据(像素数据) MemoryStream ms = new MemoryStream(); //无符号<a target=_blank href="http://baike.baidu.com/view/8420446.htm" target="_blank">字节数组</a>形式存储的数据,以内存作为存储区 bitmap.Save(ms, ImageFormat.Jpeg); //将此图像以指定的格式保存到指定的流中。 byte[] byteImage = new Byte[ms.Length]; byteImage = ms.ToArray(); //将流写入到字节数组 client.Send(byteImage, byteImage.Length, Ipe); //发送
step3:发送数据
IPEndPoint Ipe = new IPEndPoint(IPAddress,Port); //实例化目的端口号; IPEndPoint Ipe= new IPEndPoint(IPAddress.Broadcast, port); // 广播模式; IPEndPoint Ipe= new IPEndPoint(); // 匿名模式,系统将为随机分配; client.Send(byteImage, byteImage.Length, Ipe); //发送数据;数据格式为字节流格式;
step4:接受数据
IPEndPoint Ipe = new IPEndPoint(IPAddress.Any,0);//IPAddress.Any表示任意IP,0表示任意端口;当然也可以设为发送的的IPAddress和Port; byte[] getData =client.Receive(ref Ipe); //从指定的IPEndpoint接收数据;
step5:数据还原
byte[] getData =client.Receive(ref Ipe); MemoryStream stream = new MemoryStream(getData); //字节数组以流的形式存储,以内存作为存储区 pictureBox1.Image = (Bitmap)((Image)new Bitmap(stream)); //将流转换为像素数据
完整代码://视频采集并发送
using System; using System.Drawing; using System.Drawing.Imaging; using System.IO; using System.Net; using System.Net.Sockets; using System.Threading; using System.Windows.Forms; namespace UDP_Sender { public partial class Form1 : Form { UdpClient client; public Form1() { InitializeComponent(); IPEndPoint Ipe = new IPEndPoint(IPAddress.Parse("127.0.0.1"), int.Parse("12345")); client = new UdpClient(Ipe); Thread CameraStartThread = new Thread(CameraStart); CameraStartThread.IsBackground = true; CameraStartThread.Start(); } //CameraOperation public void CameraStart() { this.photoPanel1.CameraIndex = 0; this.photoPanel1.Start(); Thread.Sleep(1000); //等待摄像头完全启动 Thread Datasender = new Thread(Sender); Datasender.IsBackground = true; Datasender.Start(); } //Data Sender public void Sender() { IPEndPoint Ipe = new IPEndPoint(IPAddress.Parse("127.0.0.2"), int.Parse("1234"));//Ipe_Receiver Bitmap bitmap; while (true) { bitmap = photoPanel1.GetCurrentImage(); MemoryStream ms = new MemoryStream(); try { bitmap.Save(ms, ImageFormat.Jpeg); } catch { } byte[] byteImage = new Byte[ms.Length]; byteImage = ms.ToArray(); MemoryStream stream = new MemoryStream(byteImage); client.Send(byteImage, byteImage.Length, Ipe); } } private void Form1_FormClosed(object sender, FormClosedEventArgs e) { photoPanel1.Stop(); } } }
数据接收、还原、显示
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Drawing.Imaging; using System.IO; using System.Linq; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; namespace UDP_Sender { public partial class Form1 : Form { UdpClient client; public Form1() { InitializeComponent(); IPEndPoint Ipe = new IPEndPoint(IPAddress.Parse("127.0.0.2"), int.Parse("12345")); client = new UdpClient(Ipe); Thread Receive_Thread = new Thread(Receive); Receive_Thread.IsBackground = true; Receive_Thread.Start(); } public void Receive() { while (true) { IPEndPoint Ipe = new IPEndPoint(IPAddress.Any, 0); byte[] getData = client.Receive(ref Ipe); MemoryStream stream = new MemoryStream(getData); pictureBox1.Image = (Bitmap)((Image)new Bitmap(stream)); } } } }
浙公网安备 33010602011771号