winsocket 一个udp的包究竟能发多大

yiyefangzhou24 2017-03-14 10:42:26
实际操作过程中发现无论我缓冲区设置多大,好像跟一个udp包数据量的大小无关,只要一个UDP包超过1024(1k)就收不到,但sendto和recvfrom都不报错,就是收不到数据,有没有办法能够手动改变一个udp包大小的?
...全文
565 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
zilaishuichina 2017-03-20
  • 打赏
  • 举报
回复
引用 6 楼 yiyefangzhou24 的回复:
[quote=引用 4 楼 zilaishuichina 的回复:] [quote=引用 3 楼 yiyefangzhou24 的回复:] [quote=引用 1 楼 zilaishuichina 的回复:] 如果你说的是逻辑包,那么理论上无限大 关键在于你发送一个大包的时候, 发送端如何拆包,接收端如何确保收包顺序,并拼包 如果你说的是upd协议封好之后的udp包 最大数据长度为 65535 - ip头20字节 - udp头8字节 = 65507字节 如果没收到数据 1、考虑是不是路由器/防火墙拦截了超出一定长度的数据包 2、考虑在收发端分别抓包确认是否发送,是否接收到
我是做了分包,每个包分了32K的大小,但是我发现sendto已经发出去了,因为返回不是-1,但是recvfrom的时候一直阻塞收不到数据,如果将包大小调至1k的时候可以正常收发。 如果分1k一个包的话,对于udp这种无序协议,组包的时候有点费劲[/quote] 就算你程序逻辑不愿意分包, 一长串数据直接到了ip层,还是会被分包的 ip协议会对数据分片,就会被分成MTU -20 -8 这么大的一个包来分段发送 如果在实际网络环境中,ip层传丢了一个包,你就得依赖上层逻辑来要求发送端重传 udp就是比较费劲,想不费劲就tcp喽[/quote]实现的是一个远程屏幕监控的一个功能,截图->压缩->传送->接受->解压缩->显示的过程,分包其实我也写了,但是我发现不同的网络环境,不同的系统一次一个包的大小不太一样,有的能一次发十几K,有的一次只能发1K,在实际环境中如何才能确定一次包大小,以便于在分包的时候知道分多少[/quote] 实际环境中的包大小,是由整个链路上的每一个转发节点(路由器)上设置的MTU的最小值决定的, linux下可以用traceroute查数据包经过的每一跳(windows下用tracert),然后一个个的ping过去,试出来 但是~ 对于应用逻辑来说,或者对于你的可靠UDP协议来说,你不需要知道这个最小MTU是多少。 就算你定的包大小,比实际环境中的最小MTU大,也没有关系,UDP下一层的IP协议会自动给你的大包分片发送的。 所以你只要保证:1、逻辑层能正确的分包,拼包,2、正确检测超时/丢失,然后重传就可以了
yiyefangzhou24 2017-03-20
  • 打赏
  • 举报
回复
引用 8 楼 zilaishuichina 的回复:
[quote=引用 6 楼 yiyefangzhou24 的回复:] [quote=引用 4 楼 zilaishuichina 的回复:] [quote=引用 3 楼 yiyefangzhou24 的回复:] [quote=引用 1 楼 zilaishuichina 的回复:] 如果你说的是逻辑包,那么理论上无限大 关键在于你发送一个大包的时候, 发送端如何拆包,接收端如何确保收包顺序,并拼包 如果你说的是upd协议封好之后的udp包 最大数据长度为 65535 - ip头20字节 - udp头8字节 = 65507字节 如果没收到数据 1、考虑是不是路由器/防火墙拦截了超出一定长度的数据包 2、考虑在收发端分别抓包确认是否发送,是否接收到
我是做了分包,每个包分了32K的大小,但是我发现sendto已经发出去了,因为返回不是-1,但是recvfrom的时候一直阻塞收不到数据,如果将包大小调至1k的时候可以正常收发。 如果分1k一个包的话,对于udp这种无序协议,组包的时候有点费劲[/quote] 就算你程序逻辑不愿意分包, 一长串数据直接到了ip层,还是会被分包的 ip协议会对数据分片,就会被分成MTU -20 -8 这么大的一个包来分段发送 如果在实际网络环境中,ip层传丢了一个包,你就得依赖上层逻辑来要求发送端重传 udp就是比较费劲,想不费劲就tcp喽[/quote]实现的是一个远程屏幕监控的一个功能,截图->压缩->传送->接受->解压缩->显示的过程,分包其实我也写了,但是我发现不同的网络环境,不同的系统一次一个包的大小不太一样,有的能一次发十几K,有的一次只能发1K,在实际环境中如何才能确定一次包大小,以便于在分包的时候知道分多少[/quote] 实际环境中的包大小,是由整个链路上的每一个转发节点(路由器)上设置的MTU的最小值决定的, linux下可以用traceroute查数据包经过的每一跳(windows下用tracert),然后一个个的ping过去,试出来 但是~ 对于应用逻辑来说,或者对于你的可靠UDP协议来说,你不需要知道这个最小MTU是多少。 就算你定的包大小,比实际环境中的最小MTU大,也没有关系,UDP下一层的IP协议会自动给你的大包分片发送的。 所以你只要保证:1、逻辑层能正确的分包,拼包,2、正确检测超时/丢失,然后重传就可以了[/quote]非常受教
Henzox 2017-03-19
  • 打赏
  • 举报
回复
http://blog.csdn.net/henzox/article/details/43233157
yiyefangzhou24 2017-03-19
  • 打赏
  • 举报
回复
引用 4 楼 zilaishuichina 的回复:
[quote=引用 3 楼 yiyefangzhou24 的回复:] [quote=引用 1 楼 zilaishuichina 的回复:] 如果你说的是逻辑包,那么理论上无限大 关键在于你发送一个大包的时候, 发送端如何拆包,接收端如何确保收包顺序,并拼包 如果你说的是upd协议封好之后的udp包 最大数据长度为 65535 - ip头20字节 - udp头8字节 = 65507字节 如果没收到数据 1、考虑是不是路由器/防火墙拦截了超出一定长度的数据包 2、考虑在收发端分别抓包确认是否发送,是否接收到
我是做了分包,每个包分了32K的大小,但是我发现sendto已经发出去了,因为返回不是-1,但是recvfrom的时候一直阻塞收不到数据,如果将包大小调至1k的时候可以正常收发。 如果分1k一个包的话,对于udp这种无序协议,组包的时候有点费劲[/quote] 就算你程序逻辑不愿意分包, 一长串数据直接到了ip层,还是会被分包的 ip协议会对数据分片,就会被分成MTU -20 -8 这么大的一个包来分段发送 如果在实际网络环境中,ip层传丢了一个包,你就得依赖上层逻辑来要求发送端重传 udp就是比较费劲,想不费劲就tcp喽[/quote]实现的是一个远程屏幕监控的一个功能,截图->压缩->传送->接受->解压缩->显示的过程,分包其实我也写了,但是我发现不同的网络环境,不同的系统一次一个包的大小不太一样,有的能一次发十几K,有的一次只能发1K,在实际环境中如何才能确定一次包大小,以便于在分包的时候知道分多少
zilaishuichina 2017-03-14
  • 打赏
  • 举报
回复
引用 3 楼 yiyefangzhou24 的回复:
[quote=引用 1 楼 zilaishuichina 的回复:] 如果你说的是逻辑包,那么理论上无限大 关键在于你发送一个大包的时候, 发送端如何拆包,接收端如何确保收包顺序,并拼包 如果你说的是upd协议封好之后的udp包 最大数据长度为 65535 - ip头20字节 - udp头8字节 = 65507字节 如果没收到数据 1、考虑是不是路由器/防火墙拦截了超出一定长度的数据包 2、考虑在收发端分别抓包确认是否发送,是否接收到
我是做了分包,每个包分了32K的大小,但是我发现sendto已经发出去了,因为返回不是-1,但是recvfrom的时候一直阻塞收不到数据,如果将包大小调至1k的时候可以正常收发。 如果分1k一个包的话,对于udp这种无序协议,组包的时候有点费劲[/quote] 就算你程序逻辑不愿意分包, 一长串数据直接到了ip层,还是会被分包的 ip协议会对数据分片,就会被分成MTU -20 -8 这么大的一个包来分段发送 如果在实际网络环境中,ip层传丢了一个包,你就得依赖上层逻辑来要求发送端重传 udp就是比较费劲,想不费劲就tcp喽
yiyefangzhou24 2017-03-14
  • 打赏
  • 举报
回复
引用 1 楼 zilaishuichina 的回复:
如果你说的是逻辑包,那么理论上无限大 关键在于你发送一个大包的时候, 发送端如何拆包,接收端如何确保收包顺序,并拼包 如果你说的是upd协议封好之后的udp包 最大数据长度为 65535 - ip头20字节 - udp头8字节 = 65507字节 如果没收到数据 1、考虑是不是路由器/防火墙拦截了超出一定长度的数据包 2、考虑在收发端分别抓包确认是否发送,是否接收到
我是做了分包,每个包分了32K的大小,但是我发现sendto已经发出去了,因为返回不是-1,但是recvfrom的时候一直阻塞收不到数据,如果将包大小调至1k的时候可以正常收发。 如果分1k一个包的话,对于udp这种无序协议,组包的时候有点费劲
www_adintr_com 2017-03-14
  • 打赏
  • 举报
回复
UDP 的最大长度是由底层网络硬件决定的. 通常以太网在链路层一个包最大为 1500 字节, 除去各部分包头UDP中的数据为 1472 字节 不过如果你的包跨越了多个路由器, 则最大数据是由中间最小的那个网络的 MTU 决定的,
zilaishuichina 2017-03-14
  • 打赏
  • 举报
回复
如果你说的是逻辑包,那么理论上无限大 关键在于你发送一个大包的时候, 发送端如何拆包,接收端如何确保收包顺序,并拼包 如果你说的是upd协议封好之后的udp包 最大数据长度为 65535 - ip头20字节 - udp头8字节 = 65507字节 如果没收到数据 1、考虑是不是路由器/防火墙拦截了超出一定长度的数据包 2、考虑在收发端分别抓包确认是否发送,是否接收到
赵4老师 2017-03-14
  • 打赏
  • 举报
回复
不要迷信书、考题、老师、回帖; 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实!
目 录 一、目录…………………………………………………………………1 二、题目……………………………………………………………2 三、设计任务…………………………………………………2 四、WinSocket简介及特点原理…………………………………2 五、TCP简介及特点原理………………………………………3 六、Visual C++简介………………………………………………7 七、设计方案…………………………………………………8 八、系统的原理框图和程序流程图………………………10 九、实验中的问题…………………………………………………14 十、实验结果及分析………………………………………………14 十一、课程设计的总结体会………………………………………16 十二、参考文献……………………………………………………16 利用Socket实现双机通信 一、设计任务 1.利用WinSock来实现双机通信,理解TCP状态机图。 2.要求使用WinSock编程,采用其中的TCP面向连接方式,实现文本数据的交换。 二、WinSocket简介及特点原理 2.1、什么是socket 所谓socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄。应 用程序通常通过"套接字"向网络发出请求或者应答网络请求。 Socket接口是TCP/IP网络的API,Socket接口定义了许多函数或例程,程序员可以用 它们来开发TCP/IP网络上的应用程序。要学Internet上的TCP/IP网络编程,必须理解So cket接口。 Socket接口设计者最先是将接口放在Unix操作系统里面的。如果了解Unix系统的输入和 输出的话,就很容易了解Socket了。网络的Socket数据传输是一种特殊的I/O,Socket也 是一种文件描述符。Socket也具有一个类似于打开文件的函数调用Socket(),该函数返 回一个整型的Socket描述符,随后的连接建立、数据传输等操作都是通过该Socket实现 的。 常用的Socket类型有两种:流式Socket(SOCK_STREAM)和数据报式Socket(SOCK_D GRAM)。流式是一种面向连接的Socket,针对于面向连接的TCP服务应用;数据报式Soc ket是一种无连接的Socket,对应于无连接的UDP服务应用。   最重要的是,socket 是面向客户/服务器模型而设计的,针对客户和服务器程序提供不同的socket 系统调用。客户随机申请一个socket (相当于一个想打电话的人可以在任何一台入网电话上拨号呼叫),系统为之分配一个so cket号;服务器拥有全局公认的 socket ,任何客户都可以向它发出连接请求和信息请求(相当于一个被呼叫的电话拥有一个呼叫 方知道的电话号码)。 socket利用客户/服务器模式巧妙地解决了进程之间建立通信连接的问题。服务器so cket 半相关为全局所公认非常重要。不妨考虑一下,两个完全随机的用户进程之间如何建立 通信?假如通信双方没有任何一方的socket 固定,就好比打电话的双方彼此不知道对方的电话号码,要通话是不可能的。 2.2、WinSocket的通信原理 WinSock是一个基于Socket模型的 API。WinSock在 Windows98,Window NT中使用。WinSock一般由两部分组成:开发组件和运行组件。开发组件是供程序员在w indows环境下开发网络应用程序使用的,它括应用程序接口库函数、头文件和实现的 文档,其中最主要的是WINSOCK.H运行组件是以动态链接库(DlL)来实现socket接口的。 文件名为WINSOCK.DLL应用程序在执行时装入它就能实现网络通信功能 三、TCP简介及特点原理 1.什么是TCP TCP是一种面向连接(连接导向)的、可靠的、基于字节流的运输层(Transport layer)通信协议。在简化的计算机网络OSI模型中,它完成第四层传输层所指定的功能 。   在因特网协议族(Internet protocol suite)中,TCP层是位于IP层之上,应用层之下的中间层。不同主机的应用层之间经常 需要可靠的、像管道一样的连接,但是IP层不提供这样的流机制,而是提供不可靠的 交换。   应用层向TCP层发送用于网间传输的、用8位字节表示的数据流,然后TCP把数据流分 割成适当长度的报文段(通常受该计算机连接的网络的数据链路层的最大传送单元(MTU )的限制)。之后TCP把结果传给IP层,由它来通过网络将传送给接收端实体的TCP层 。TCP为了保证不发生丢,就给每个字节一个序号,同时序号也保证了传送到接收端实 体的的按序接收。然后接收端实体对已成功收到的字节发回一个相应的确认(ACK)
本文章将介绍如何使用RawSocket(原始套接字)开发网络嗅探器: 首先我们得了解什么是套接字,这个我就不多说,自己百度,百度百科比我说的好。 那么什么又是原始套接字呢,常用的套接字分为 SOCK_STREAM(流套接字) 用于TCPXY通讯。 SOCK_DGRAM(数据报套接字) 同于UDPXY通讯。 那么原始呢,他则是和名字一样原始套接字;举例:要想用流套接字进行一次TCP的发,那么直接连接上对方服务器然后用Send就可以发送指定的内容,但其实发送的数据并不止你的那些内容,有一些东西是流套接字会给你自动补上的。TCP是属于IPXY的一个子XY,那么要发送一个TCP数据就得加上(以太网XY报头这个先不提),IPXY的报头,和TCPXY报头,这些东西流套接字都会帮你处理,而原始套接字则不会(当然也可以设置让原始套接字构造IP报头)。原始套接字他有更多的用途,但相对来说也比流套接字或数据报套接字麻烦。 原始套接字还可以设置成允许接收本地所有的套接字数据。那么我们就利用这个功能来做嗅探器! 首先:1.使用  WSAStartup (合并短整数 (2, 2), WSADATA)  来初始化Winsocket服务 其参数有2个  第一个 (短整数型/双字节型):wVersionRequired  这个参数表明使用的winsock版本号,高位指定修订版本号,低位指定主版本号。第二个参数 WSADATA类型 用于接收Winsocket细节东西,咱不用管它。 //下面就不说那么详细了,源码里面全是注释,自己看。 2.然后使用socket (#AF_INET, #SOCK_RAW, #IPPROTO_IP)  来创建一个套接字   第一个参数应该是表明Internet地址格式反正只能固定这个,仅仅支持这个  参数2:表明要创建的是一个原始套接字,参数3:指定IPXY  IPXY括其子XY TCP UDP 等。成功返回套接字句柄 3.  bind (s, addr, sizeof (addr))  将套接字绑定至指定网卡,参数1=套接字句柄    参数2为一个addr结构的值,该值表明要绑定的网卡IP及端口号 4.  ioctlsocket (Socket, 2550136833, 1) 将套接字的模式改变为允许接收所有数据 顺利完成上面的操作后咱就可以用Recv来接收数据了,只要不断的调用Recv就OK。

64,639

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧