程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> C#基於Udp的分包傳輸

C#基於Udp的分包傳輸

編輯:C#入門知識

   因為要遠做程攝像頭監控,要用到網絡數據傳輸,百度了一下,很多就是基於Tcp的,因為QQ是用Udp,所有我也嘗試用Udp。

要用Udp傳輸數據,就免不了分包和重包,因為Udp最大只能傳輸64KB的數據!下面給出分包的代碼:

   首先定義一個包類:

using System;
using System.Collections.Generic;

namespace Packet_Library
{


    /// <summary>
    /// 包類
    /// </summary>
    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;
        }
        /// <summary>
        /// 索引序號
        /// </summary>
        public int Index
        {
            get { return _index; }
            set { _index = value; }
        }
        /// <summary>
        /// 數據
        /// </summary>
        public byte[] Data
        {
            get { return _data; }
            set { _data = value; }
        }
        /// <summary>
        /// 狀態,用來記錄包的開始和結束。1:開始,2:中間,3:包尾。
        /// </summary>
        public int State
        {
            get { return _state; }
            set { _state = value; }
        }
    }

}

 

再定義一個處理包的類:

using System;
using System.Collections.Generic;

namespace Packet_Library
{
    /// <summary>
    /// 分包
    /// </summary>
    public class PacketSplitter
    {
        private static int defaultPartSize = 1024;
        /// <summary>
        /// 分包
        /// </summary>
        /// <param name="datagram">數據包</param>
        /// <param name="partSize">塊大小(小於1024*64)</param>
        /// <returns>分包列表</returns>
        public static List<Packet> Split(byte[] datagram, int partSize)
        {
            defaultPartSize = partSize;
            return Split(datagram);

        }

        /// <summary>
        /// 分包
        /// </summary>
        /// <param name="datagram">數據包(使用默認塊大小:1024 byte)</param>
        /// <returns>分包列表</returns>
        public static List<Packet> Split(byte[] datagram)
        {
            List<Packet> packets = new List<Packet>();
            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;
        }

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved