因为要远做程摄像头监控,要用到网络数据传输,百度了一下,很多就是基于Tcp的,因为QQ是用Udp,所有我也尝试用Udp。
要用Udp传输数据,就免不了分包和重包,因为Udp最大只能传输64KB的数据!下面给出分包的代码:
首先定义一个包类:
using System;
using System.Collections.Generic;
namespace Packet_Library
{
///
/// 包类
///
public class Packet
{
private int _index;
private byte[] _data;
private int _state;
public Packet(int index, byte[] buffer,int state)
{
this._index = index;
this._data = buffer;
this._state = state;
}
///
/// 索引序号
///
public int Index
{
get { return _index; }
set { _index = value; }
}
///
/// 数据
///
public byte[] Data
{
get { return _data; }
set { _data = value; }
}
///
/// 状态,用来记录包的开始和结束。1:开始,2:中间,3:包尾。
///
public int State
{
get { return _state; }
set { _state = value; }
}
}
}
再定义一个处理包的类:
using System;
using System.Collections.Generic;
namespace Packet_Library
{
///
/// 分包
///
public class PacketSplitter
{
private static int defaultPartSize = 1024;
///
/// 分包
///
/// 数据包
/// 块大小(小于1024*64)
///
public static List
{
defaultPartSize = partSize;
return Split(datagram);
}
///
/// 分包
///
/// 数据包(使用默认块大小:1024 byte)
///
public static List
{
List
if (datagram == null)
return null;
if (datagram.Length <= defaultPartSize)
{
packets.Add(new Packet(0, datagram, 1));
return packets;
}
int _length = datagram.Length;
int counts = _length / defaultPartSize;
int remainder = _length % defaultPartSize;
int tatal = counts;
if (remainder > 0)
counts++;
for (int i = 0; i < counts; i++)
{
int _size = defaultPartSize;
if (_length - defaultPartSize * i < defaultPartSize)
_size = _length - defaultPartSize * i;
byte[] tmp = new byte[_size];
Buffer.BlockCopy(datagram, defaultPartSize * i, tmp, 0, _size);
int state = 2;
if (i == 0)
state = 1;
if (i == counts - 1)
state = 3;
packets.Add(new Packet(i, tmp, state));
}
return packets;
}
}
}
因为Udp是无连接的,所以我也模拟握手方式来进行数据传输,不要跟我说什么是握手,如果真的不知道的话,那我就再啰嗦几句。所谓握手是一个连接方式,就像我们打电话,首先你拔号,再等待,如果对方接了,你们才可以通话。Tcp就是这样的!
在Udp[中,我们可以先定义几个指令:
public Enum Commands{
requestVideoCapital=1,//请求获取视频
requestSendPacket=2,//请求发送数据包
ResponseSendPacket=3,//回应发送数据包
ResponseEndPacket=4//数据包传送结束
}
通过这几个指令,我们就可以远程视频了。这是一个这样的过程:
首先接收端请求视频(requestVideoCapital)-->发送端收到并获取摄像头的图片进行分包(ResponseSendPacket),再发送第一个包-->接收端收到包并请求下一个包(requestSendPacket)-->发送端判断是否包尾,如果包尾,就通知客户(ResponseEndPacket)-->接收端判断是否包尾,如果是,就重包,并再请求(requestVideoCapital)形成一个循环的网络传输,这样就是一个视频实时监控了!
下面说说接收端重包的方法:
我们首先定义一个存储包的数组:
private byte[] imageBuffer;
在重新请求的时候,将 imageBuffer=null;
当收到包的时候:CopyData(data);
private void CopyData(byte[] data)
{
if (imageBuffer == null)
{
imageBuffer = data;
return;
}
byte[] buffer = new byte[imageBuffer.Length + data.Length];
Buffer.BlockCopy(imageBuffer, 0, buffer, 0, imageBuffer.Length);
Buffer.BlockCopy(data, 0, buffer, imageBuffer.Length, data.Length);
imageBuffer = buffer;
}
写了这么多了,还是附上源码才是硬道理:
http://download.csdn.net/detail/keepmoving0407/5482837