精华内容
参与话题
问答
  • UDP传输数据包的大小

    千次阅读 2018-08-02 15:48:46
    1500字节被称为链路层的MTU(最大传输单元).1500-20-8=1472 在普通的局域网环境下,我建议将UDP的数据控制在1472字节以下为好 还有地方说还应该有个PPP的包头包尾的开销(8Bytes),那就为1492了 UDP 包的大小就应该...

    之前面试被问了,后来查了一下,但是太详细,有时也不好。

    1500字节被称为链路层的MTU(最大传输单元).1500-20-8=1472

    在普通的局域网环境下,我建议将UDP的数据控制在1472字节以下为好

    还有地方说还应该有个PPP的包头包尾的开销(8Bytes),那就为1492了

    UDP 包的大小就应该是 1492 - IP头(20) - UDP头(8) = 1464(BYTES)
    TCP 包的大小就应该是 1492 - IP头(20) - TCP头(20) = 1452(BYTES)

    鉴于Internet上的标准MTU值为576字节,所以我建议在进行Internet的UDP编程时.最好将UDP的数据长度控件在548字节(576-8-20)以内.(8为UDP头。20为IP头)

    展开全文
  • UDP是不可靠传输,进行数据传递时,会有数据包丢失。[color=#FF0000]我们已经做了重传机制,[/color]在有数据包丢失后,进行传输。 但是还有问题,刚开始使用时,传输比较稳定,用了一段时间后,就有发送失败的...
  • 一、套接字Socket 1.端口是用来标识一个进程的

    一、套接字Socket
    1.端口是用来标识一个进程的

    二、UDP传输过程
    应用层(data)—传输层(port)—网络层(ipv4)—链路层(mac)

    三、如何UDP网络传输发送数据?
    代码

    三、UDP广播:
    1.广播的类型:单播—多播—广播的区别
    2.接收过程:网卡—IP—端口—数据
    过程截图!!!!!!
    3.特点:只管发,不管对方有没有接收到,发到目的主机的网络层,不一定能到传输层
    4.缺点:用不好会引发堵塞,广播风暴

    四、如何UDP广播?

    展开全文
  • 对方发给我的包分两种类型,一种是命令,一种是数据,二者的长度是不同的,命令只有一个数据包(<1000字节,长度不定),数据可能分多个包。现在只是在发送的时候在头部加了标记,来区分命令和数据(如果是数据,...
  • 在c#有关udp可靠传输(包传输数据包) 我们讨论,UDP包的发送,可是上一个程序有一个问题。就是数据比較大。一个Message类序列化后都有2048B,而实际的数据量也就只是 50B罢了,这就说明当中数据有效的非常少。这样当...

    c#有关udp可靠传输(包传输数据包) 我们讨论,UDP包的发送,可是上一个程序有一个问题。就是数据比較大。一个Message类序列化后都有2048B,而实际的数据量也就只是 50B罢了,这就说明当中数据有效的非常少。这样当传送的数据包过多后,效率会极大的降低。

    因此我们仅仅有想办法降低冗余数据。

    此项目中借用了飞鸽传书中的一个《FSLib.IPMessager》项目中的思想,并加以改善。感谢此项目作者,让我对此有了深刻的理解

    我们须要自定义数据的传输结构    我们能够定义一个数据头  当中包括一些主要的必要信息。然后再把要传送的数据写入尾部。

    我把这部分代码贴出来。要详细完整的项目请到我的资源区下载,因为LZ原创希望给点分哈!

    项目下载地址

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Net;
    
    namespace Netframe.Model
    {
        /// <summary>
        /// 消息封包类
        /// </summary>
        public class MessagePacker
        {
            /*
    		 * 消息包注意:
    		 * 1.第一位始终是2(ASCII码50)
    		 * 2.第二位到第九位是一个long类型的整数,代表消息编号
    		 * 3.第十位到第十三位是一个int类型的整数,代表消息内容总长度
    		 * 4.第十四位到第十七位是一个int类型的整数,代表分包的总数
    		 * 5.第十八位到第二十一位是一个int类型的整数。代表当前的分包编号
    		 * 6.第二十二位表示是否须要返回一个确认标识(1/0)
    		 * 7.第二十三到第三十一位是保留的(Reserved)
    		 * 8.第三十二字节以后是数据包
    		 * */
    
            /// <summary>
            /// 消息版本
            /// </summary>
            public static byte VersionHeader { get { return 50; } }
            /// <summary>
            /// 返回当前消息封包的头字节数
            /// </summary>
            public static int PackageHeaderLength { get { return 32; } }
    
            /// <summary>
            /// 获得消息包的字节流
            /// </summary>
            /// <param name="message">要打包的消息对象</param>
            /// <returns></returns>
            public static UdpPacketMsg[] BuildNetworkMessage(Msg message)
            {
                if (message.ExtendMessageBytes != null)
                {
                    return BuildNetworkMessage(
                    message.RemoteAddr,
                    message.PackageNo,
                    message.Command,
                    message.UserName,
                    message.HostName,
                    message.Type,
                    message.NormalMsgBytes,
                    message.ExtendMessageBytes,
                    message.IsRequireReceive
                    );
                }
                else
                {
                    return BuildNetworkMessage(
                    message.RemoteAddr,
                    message.PackageNo,
                    message.Command,
                    message.UserName,
                    message.HostName,
                    message.Type,
                    System.Text.Encoding.Unicode.GetBytes(message.NormalMsg),
                    System.Text.Encoding.Unicode.GetBytes(message.ExtendMessage),
                    message.IsRequireReceive
                    );
                }
            }
    
            /// <summary>
            /// 获得消息包的字节流
            /// </summary>
            /// <param name="remoteIp">远程主机地址</param>
            /// <param name="packageNo">包编号</param>
            /// <param name="command">命令</param>
            /// <param name="options">參数</param>
            /// <param name="userName">username</param>
            /// <param name="hostName">主机名</param>
            /// <param name="content">正文消息</param>
            /// <param name="extendContents">扩展消息</param>
            /// <returns></returns>
            public static UdpPacketMsg[] BuildNetworkMessage(IPEndPoint remoteIp, long packageNo, Commands command, string userName, string hostName,Consts type ,byte[] content, byte[] extendContents, bool RequireReceiveCheck)
            {
    
                //每次发送所能容下的数据量
                int maxBytesPerPackage = (int)Consts.MAX_UDP_PACKAGE_LENGTH - PackageHeaderLength;
                //压缩数据流
                System.IO.MemoryStream ms = new System.IO.MemoryStream();
                System.IO.Compression.GZipStream zip = new System.IO.Compression.GZipStream(ms, System.IO.Compression.CompressionMode.Compress);
                System.IO.BinaryWriter bw = new System.IO.BinaryWriter(zip, System.Text.Encoding.Unicode);
                //写入头部数据
                bw.Write(packageNo);			//包编号
                bw.Write(userName);				//username
                bw.Write(hostName);				//主机名
                bw.Write((long)command);        //命令
                bw.Write((long)type);           //数据类型
                bw.Write(content == null ? 0 : content.Length);//数据长度
    
                //写入消息数据
                if (content != null) 
                    bw.Write(content);
                bw.Write(extendContents == null ? 0 : extendContents.Length);//补充数据长度
                if (extendContents != null) 
                    bw.Write(extendContents);
                //bw.Close();
                //zip.Close();
                ms.Flush();
                ms.Seek(0, System.IO.SeekOrigin.Begin);
    
                //打包数据总量
                int dataLength = (int)ms.Length;
    
                int packageCount = (int)Math.Ceiling(dataLength * 1.0 / maxBytesPerPackage);
                UdpPacketMsg[] pnma = new UdpPacketMsg[packageCount];
                for (int i = 0; i < packageCount; i++)
                {
                    int count = i == packageCount - 1 ? dataLength - maxBytesPerPackage * (packageCount - 1) : maxBytesPerPackage;
    
                    byte[] buf = new byte[count + PackageHeaderLength];
                    buf[0] = VersionHeader;//版本 第1位 
                    BitConverter.GetBytes(packageNo).CopyTo(buf, 1);//消息编号 第2到9位 long类型的整数
                    BitConverter.GetBytes(dataLength).CopyTo(buf, 9);//消息内容长度 第10到13位 int类型的整数
                    BitConverter.GetBytes(packageCount).CopyTo(buf, 13);//分包总数 第14位到第17位 int类型的整数
                    BitConverter.GetBytes(i).CopyTo(buf, 17);//分包编号 第18位到第21位 int类型的整数
                    buf[21] = RequireReceiveCheck ? (byte)1 : (byte)0;//是否回确认包 第22位 
                    //第23到第31位是保留的(Reserved)
                    ms.Read(buf, 32, buf.Length - 32);//第32字节以后是,详细的数据包
    
                    pnma[i] = new UdpPacketMsg()
                    {
                        Data = buf,
                        PackageCount = packageCount,
                        PackageIndex = i,
                        PackageNo = packageNo,
                        RemoteIP = remoteIp,
                        SendTimes = 0,
                        Version = 2,
                        IsRequireReceiveCheck = buf[21] == 1
                    };
                }
                bw.Close();
                zip.Close();
                ms.Close();
    
                return pnma;
            }
    
    
            /// <summary>
            /// 检測确认是否是这个类型的消息包
            /// </summary>
            /// <param name="buffer"></param>
            /// <returns></returns>
            public static bool Test(byte[] buffer)
            {
                return buffer != null && buffer.Length > PackageHeaderLength && buffer[0] == VersionHeader;
            }
    
            /// <summary>
            /// 缓存接收到的片段
            /// </summary>
            static Dictionary<long, UdpPacketMsg[]> packageCache = new Dictionary<long, UdpPacketMsg[]>();
    
            /// <summary>
            /// 分析网络数据包并进行转换为信息对象
            /// </summary>
            /// <param name="packs">接收到的封包对象</param>
            /// <returns></returns>
            /// <remarks>
            /// 对于分包消息,假设收到的仅仅是片段而且尚未接收全然。则不会进行解析
            /// </remarks>
            public static Msg ParseToMessage(params UdpPacketMsg[] packs)
            {
                if (packs.Length == 0 || (packs[0].PackageCount > 1 && packs.Length != packs[0].PackageCount))
                    return null;
    
                //尝试解压缩,先排序
                Array.Sort(packs);
                //尝试解压缩
                System.IO.MemoryStream ms = new System.IO.MemoryStream();
                System.IO.Compression.GZipStream zip = new System.IO.Compression.GZipStream(ms, System.IO.Compression.CompressionMode.Decompress);
                //System.IO.BinaryWriter bw = new System.IO.BinaryWriter(zip, System.Text.Encoding.Unicode);
                try
                {
                    foreach (var s in packs)
                    {
                        if (zip.CanWrite)
                        {
                            zip.Write(s.Data, 0, s.Data.Length);
                        }
                    }
                    
                    //Array.ForEach(packs, s => zip.Write(s.Data, 0, s.Data.Length));
                }
                catch (Exception e)
                {
                    //触发事件
                    return null;
                }
    
                zip.Close();
                ms.Flush();
                ms.Seek(0, System.IO.SeekOrigin.Begin);
    
                //构造读取流
                System.IO.BinaryReader br = new System.IO.BinaryReader(ms, System.Text.Encoding.Unicode);
    
                //開始读出数据
                Msg m = new Msg(packs[0].RemoteIP);
                m.PackageNo = br.ReadInt64();//包编号
    
                m.UserName = br.ReadString();//username
                m.HostName = br.ReadString();//主机名
                m.Command = (Commands)br.ReadInt64(); //命令
                m.Type = (Consts)br.ReadInt64();//数据类型
                int length = br.ReadInt32(); //数据长度
                m.NormalMsgBytes = new byte[length];
                br.Read(m.NormalMsgBytes, 0, length);//读取内容
    
                length = br.ReadInt32();    //附加数据长度
                m.ExtendMessageBytes = new byte[length];
                br.Read(m.ExtendMessageBytes, 0, length);//读取附加数据
    
                if (m.Type == Consts.MESSAGE_TEXT)
                {
                    m.NormalMsg = System.Text.Encoding.Unicode.GetString(m.NormalMsgBytes, 0, length);	//正文
                    m.ExtendMessage = System.Text.Encoding.Unicode.GetString(m.ExtendMessageBytes, 0, length);	//扩展消息
                    m.ExtendMessageBytes = null;
                    m.NormalMsgBytes = null;
    
                }
                return m;
            }
    
            /// <summary>
            /// 尝试将收到的网络包解析为实体
            /// </summary>
            /// <param name="pack">收到的网络包</param>
            /// <returns></returns>
            /// <remarks>假设收到的包是分片包,且其全部子包尚未接受全然,则会返回空值</remarks>
            public static Msg TryToTranslateMessage(UdpPacketMsg pack)
            {
                if (pack == null || pack.PackageIndex >= pack.PackageCount - 1) return null;
                else if (pack.PackageCount == 1) return ParseToMessage(pack);
                else
                {
                    if (packageCache.ContainsKey(pack.PackageNo))
                    {
                        UdpPacketMsg[] array = packageCache[pack.PackageNo];
                        array[pack.PackageIndex] = pack;
    
                        //检測是否完整
                        if (Array.FindIndex(array, s => s == null) == -1)
                        {
                            packageCache.Remove(pack.PackageNo);
                            return ParseToMessage(array);
                        }
                        else
                        {
                            return null;
                        }
                    }
                    else
                    {
                        UdpPacketMsg[] array = new UdpPacketMsg[pack.PackageCount];
                        array[pack.PackageIndex] = pack;
                        packageCache.Add(pack.PackageNo, array);
                        return null;
                    }
                }
    
            }
    
            /// <summary>
            /// 将网络信息解析为封包
            /// </summary>
            /// <param name="buffer"></param>
            /// <returns></returns>
            public static UdpPacketMsg Parse(byte[] buffer, IPEndPoint clientAddress)
            {
                if (!Test(buffer)) return null;
    
                UdpPacketMsg p = new UdpPacketMsg()
                {
                    RemoteIP = clientAddress,
                    SendTimes = 0
                };
                p.PackageNo = BitConverter.ToInt64(buffer, 1);//包编号
                p.DataLength = (int)BitConverter.ToInt64(buffer, 9); //内容长度
                p.PackageCount = BitConverter.ToInt32(buffer, 17);//分包总数
                p.PackageIndex = BitConverter.ToInt32(buffer, 21);//索引
                p.IsRequireReceiveCheck = buffer[21] == 1;//是否须要回包
                p.Data = new byte[buffer.Length - PackageHeaderLength];
                Array.Copy(buffer, PackageHeaderLength, p.Data, 0, p.Data.Length);
    
                return p;
            }
    
        }
    }
    


    展开全文
  • UDP用户数据包协议

    千次阅读 2012-03-25 21:32:47
    一.简介 ... UDP和TCP(传输控制协议)都属于传输层协议,UDP与TCP协议一样用于处理数据包,在OSI模型中的第四层--传输层,处于IP(网际协议)的上一层。UDP有不提供数据包分组、组装和不能对数据包

    一.简介

            UDP 是User Datagram Protocol(用户数据包协议)的简称,是OSI参考模型中一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务。

           UDP和TCP(传输控制协议)都属于传输层协议,UDP与TCP协议一样用于处理数据包,在OSI模型中的第四层--传输层,处于IP(网际协议)的上一层。UDP有不提供数据包分组、组装和不能对数据包进行排序的缺点,也就是说,当报文发送之后,是无法得知其是否安全完整到达的。UDP用来支持那些需要在计算机之间传输数据的网络应用。包括网络视频会议系统、QQ在内的众多的客户/服务器模式的网络应用都需要使用UDP协议。

        在网络质量令人不十分满意的环境下,UDP协议数据包丢失会比较严重。

      

    UDP

    二.UDP协议特点

           (1) UDP是一个无连接协议,传输数据之前源端和终端不建立连接,当
    它想传送时就简单地去抓取来自应用程序的数据,并尽可能快地把它扔到网络上。在发送端,UDP传送数据的速度仅仅是受应用程序生成数据的速度、计算机的能力和传输带宽的限制;在接收端,UDP把每个消息段放在队列中,应用程序每次从队列中读一个消息段。

      (2) 由于传输数据不建立连接,因此也就不需要维护连接状态,包括收发状态等,因此处理速度比TCP快,一台服务机可同时向多个客户机传输相同的消息。

      (3) UDP信息包的标题很短,只有8个字节,相对于TCP的20个字节信息包的额外开销很小。
      (4) 吞吐量不受拥挤控制算法的调节,只受应用软件生成数据的速率、传输带宽、源端和终端主机性

    能的限制。
      (5)UDP使用尽最大努力交付即不保证可靠交付,会有丢包现象,因此主机不需要维持复杂的链接状态表(这里面有许多参数)。

      (6)UDP是面向报文的。发送方的UDP对应用程序交下来的报文,在添加首部后就向下交付给IP层。既不拆分,也不合并,而是保留这些报文的边界,因此,应用程序需要选择合适的报文大小。


    三.UDP数据包大小

              以太网(Ethernet)数据帧的长度必须在46-1500字节之间,这是由以太网的物理特性决定的.这个1500字节被称为链路层的MTU(最大传输单元).但这并不是指链路层的长度被限制在1500字节,其实这个MTU指的是链路层的数据区.并不包括链路层的首部和尾部的18个字节.所以,事实上,这个1500字节就是网络层IP数据报的长度限制.因为IP数据报的首部为20字节,所以IP数据报的数据区长度最大为1480字节.而这个1480字节就是用来放TCP传来的TCP报文段或UDP传来的UDP数据报的.又因为UDP数据报的首部8字节,所以UDP数据报的数据区最大长度为1472字节.这个1472字节就是我们可以使用的字节数。


    展开全文
  • 转载于:https://www.cnblogs.com/jodyccf/p/10476615.html
  • TCP、UDP数据包传输

    千次阅读 2012-08-06 09:28:01
    UDP和TCP协议利用端口号实现多项应用同时发送和接收数据。数据通过源端口发送出去,通过目标端口接收。...因为UDP和TCP报头使用两个字节存放端口号... MTU最大传输单元,这个最大传输单元实际上和链路层协议有着密切的关
  • UDP传输中的数据包长度问题

    千次阅读 2013-05-24 17:22:48
    在链路层,数据帧的内容最大为1500,即MTU...在传输层,对于UDP包的首部要占用8字节,所以这的MTU为1480-8=1472; 在应用层,你的Data最大长度为1472。 (当我们的UDP包中的数据多于MTU(1472)时,发送方的IP
  • 两台计算机型号和千兆以太网卡全部相同,其中一台计算机作为服务器端,另一台作为客户端,两者通过socket建立连接(udp连接),客户端单次向服务器端发送一百万数据包(每个数据包大小为1024字节),服务器端只接收...
  • UDP数据包最大传输长度

    千次阅读 2017-11-07 20:32:37
    这个1500字节被称为链路层的MTU(最大传输单元). 但这并不是指链路层的长度被限制在1500字节,其实这这个MTU指的是链路层的数据区.并不包括链路层的首部和尾部的18个字节. 所以,事实上,这个1500字节就是网络层IP数据...
  • 之前因为要解决项目的IPv6问题,去CocoaAsyncSocket逛了一下,看到一个...问题很简单,使用UDP传输图片,可是当图片大小超过9K的时候无法发送。 开始我想的很简单。因为MTU的限制,所以9K大小的数据报肯定被分片了。...
  • MTU最大传输单元,这个最大传输单元实际上和链路层协议有着密切的关系,EthernetII帧的结构DMAC+SMAC+Type+Data+CRC由于以太网传输电气方面的限制,每个以太网帧都有最小的大小64bytes最大不能超过1518bytes,对于...
  • 这篇文章写了udp的通讯 然后我自己添加了录音的部分 使用了AudioUnit 这种方案可以做到低延时 还添加了AudioQueue的方案进行播放 因为udp的不可靠性 我要防止udp的丢包和粘包 于是加上了 协议头 音频标识 音频...
  •  其中以太网(Ethernet)的数据帧在链路层 IP包在网络层 TCP或UDP包在传输层 TCP或UDP中的数据(Data)在应用层 它们的关系是 数据帧{IP包{TCP或UDP包{Data}}} 在应用程序中我们用到的Data的长度最大是...
  • UDP数据包可靠传输实现方案

    千次阅读 2015-09-21 20:58:06
    本文的主要工作是解决网关B下主机和网关C下主机之间的udp数据包可靠传输问题,采用基于udp的可靠传输协议UDT来实现udp数据包的可靠传输。网关B下的客户端A是发送udp数据包的请求端,网关C下的服务器D是udp数据包的...

空空如也

1 2 3 4 5 ... 20
收藏数 3,920
精华内容 1,568
关键字:

udp传输数据包