问题:
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));
}
}
}
}