• 包stateC#基于Udp的分包传输


    工作之余抽点时间出来写写博文,希望对新接触的朋友有帮助。今天在这里和大家一起学习一下包state

       因为要远做程摄像头监控,要用到网络数据传输,百度了一下,很多就是基于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;
            }

        写了这么多了,还是附上源码才是硬道理:

     http://download.csdn.net/detail/keepmoving0407/5482837

    文章结束给大家分享下程序员的一些笑话语录: 那是习惯决定的,一直保持一个习惯是不好的!IE6的用户不习惯多标签,但是最终肯定还是得转到多标签的浏览器。历史(软件UI)的进步(改善)不是以个人意志(习惯)为转移的!

    --------------------------------- 原创文章 By
    包和state
    ---------------------------------

  • 相关阅读:
    HDFS原理
    shell定时采集数据到HDFS
    HDFS的JavaAPI
    HDFS基本操作
    Kettle 数据抽取
    Matlab 实现对码功能
    医院就诊流程解析
    使用 Python 在 Caché 和 Sql Server 之间同步数据
    Matlab 日期频次统计
    使用 Python 连接 Caché 数据库
  • 原文地址:https://www.cnblogs.com/xinyuyuanm/p/3109120.html
Copyright © 2020-2023  润新知