java TCP传输数据有没有大小限制,有,是多少,没有,为什么?

作者&投稿:隆刷 (若有异议请与网页底部的电邮联系)
java TCP socket 发送了18000个字节的数据却只接收到5000字节之后全部被空格填满至18000字节,这是啥原因~

Socket的Send,Recv的长度问题:
一个包没有固定长度,以太网限制在46-1500字节,1500就是以太网的MTU,超过这个量,TCP会为IP数据报设置偏移量进行分片传输,现在一般可允许应用层设置8k(NTFS系统)的缓冲区,8k的数据由底层分片,而应用层看来只是一次发送。
windows的缓冲区经验值是4k。
Socket本身分为两种,流(TCP)和数据报(UDP),你的问题针对这两种不同使用而结论不一样。甚至还和你是用阻塞、还是非阻塞Socket来编程有关。
1、通信长度,这个是你自己决定的,没有系统强迫你要发多大的包,实际应该根据需求和网络状况来决定。对于TCP,这个长度可以大点,但要知道,Socket内部默认的收发缓冲区大小大概是8K,你可以用SetSockOpt来改变。但对于UDP,就不要太大,一般在1024至10K。注意一点,你无论发多大的包,IP层和链路层都会把你的包进行分片发送,一般局域网就是1500左右,广域网就只有几十字节。分片后的包将经过不同的路由到达接收方,对于UDP而言,要是其中一个分片丢失,那么接收方的IP层将把整个发送包丢弃,这就形成丢包。显然,要是一个UDP发包佷大,它被分片后,链路层丢失分片的几率就佷大,你这个UDP包,就佷容易丢失,但是太小又影响效率。最好可以配置这个值,以根据不同的环境来调整到最佳状态。
send()函数返回了实际发送的长度,在网络不断的情况下,它绝不会返回(发送失败的)错误,最多就是返回0。对于TCP你可以写一个循环发送。当send函数返回SOCKET_ERROR时,才标志着有错误。但对于UDP,你不要写循环发送,否则将给你的接收带来极大的麻烦。所以UDP需要用SetSockOpt来改变Socket内部Buffer的大小,以能容纳你的发包。明确一点,TCP作为流,发包是不会整包到达的,而是源源不断的到,那接收方就必须组包。而UDP作为消息或数据报,它一定是整包到达接收方。
2、关于接收,一般的发包都有包边界,首要的就是你这个包的长度要让接收方知道,于是就有个包头信息,对于TCP,接收方先收这个包头信息,然后再收包数据。一次收齐整个包也可以,可要对结果是否收齐进行验证。这也就完成了组包过程。UDP,那你只能整包接收了。要是你提供的接收Buffer过小,TCP将返回实际接收的长度,余下的还可以收,而UDP不同的是,余下的数据被丢弃并返回WSAEMSGSIZE错误。注意TCP,要是你提供的Buffer佷大,那么可能收到的就是多个发包,你必须分离它们,还有就是当Buffer太小,而一次收不完Socket内部的数据,那么Socket接收事件(OnReceive),可能不会再触发,使用事件方式进行接收时,密切注意这点。这些特性就是体现了流和数据包的区别。
补充一点,接收BuffSize >= 发送BuffSize >= 实际发送Size,对于内外部的Buffer都适用,上面讲的主要是Socket内部的Buffer大小关系。
3、TCP是有多少就收多少,如果没有当然阻塞Socket的recv就会等,直到有数据,非阻塞Socket不好等,而是返回WSAEWOULDBLOCK。UDP,如果没有数据,阻塞Socket就会等,非阻塞Socket也返回WSAEWOULDBLOCK。如果有数据,它是会等整个发包到齐,并接收到整个发包,才返回。

可能的原因:1.交换机或路由器过载使TCP包或确认包丢失;2.接收端对TCP包的确认速度慢,致使发送端超时重发;3.接收端缓存溢出;4.TCP数据包在传输过程中丢失或损坏;5.发送端与接收端之间的距离太远或传输速度太慢;请检查:1.交换机或路由器的工作状态;2.接收主机正在运行的服务;3.检查接收主机的工作状态 如果你是个体家庭如:如ADSL用户说明你的电话线距离插盒较远可以适当调整,最好给当地的服务商的客服联系如果你是局域网用户:说明路由器需要重新设置,或者用户过多很想帮你可是你提供的信息不够全面

MTU最大传输单元,这个最大传输单元实际上和链路层协议有着密切的关系,EthernetII帧的结构DMAC+SMAC+Type+Data+CRC由于以太网传输电气方面的限制,每个以太网帧都有最小的大小64bytes最大不能超过1518bytes,对于小于或者大于这个限制的以太网帧我们都可以视之为错误的数据帧,一般的以太网转发设备会丢弃这些数据帧。
由于以太网EthernetII最大的数据帧是1518Bytes这样,刨去以太网帧的帧头(DMAC目的MAC地址48bit=6Bytes+SMAC源MAC地址48bit=6Bytes+Type域2bytes)14Bytes和帧尾CRC校验部分4Bytes那么剩下承载上层协议的地方也就是Data域最大就只能有1500Bytes这个值我们就把它称之为MTU。
PPPoE所谓PPPoE就是在以太网上面跑PPP协议,有人奇怪了,PPP协议和Ethernet不都是链路层协议吗?怎么一个链路层跑到另外一个链路层上面去了,难道升级成网络层协议了不成。其实这是个误区:就是某层协议只能承载更上一层协议。
为什么会产生这种奇怪的需求呢?这是因为随着宽带接入(这种宽带接入一般为Cable Modem或者xDSL或者以太网的接入),因为以太网缺乏认证计费机制而传统运营商是通过PPP协议来对拨号等接入服务进行认证计费的.
PPPoE带来了好处,也带来了一些坏处,比如:二次封装耗费资源,降低了传输效能等等,这些坏处俺也不多说了,最大的坏处就是PPPoE导致MTU变小了以太网的MTU是1500,再减去PPP的包头包尾的开销(8Bytes),就变成1492。
UDP 包的大小就应该是 1492 - IP头(20) - UDP头(8) = 1464(BYTES)
TCP 包的大小就应该是 1492 - IP头(20) - TCP头(20) = 1452(BYTES)
目前大多数的路由设备的MTU都为1500
我对上面的理解是:如果我们定义的TCP和UDP包小于1452,1464,那么我们的包在IP层就不用分包了,这样传输过程中就避免了在IP层组包发生的错误。如果使用UDP协议,如果IP层组包发生错误,那么包就会被丢弃,UDP不保证可靠传输。但是TCP发生组包错误时,该包会被重传,保证可靠传输。所以,我们在用Socket编程时,包的大小设定不一定非要小于1400,UDP协议要求包小于64K,TCP没有限定

有速度限制,没有大小限制,在linux里可以配置限速。

学习下


江苏省17013675384: java 怎么判断远程服务器上某个文件是否存在 -
仉宗五味: 如果你的JAVA部署的tomcat,就是你要查找文件的服务器,那就用:File file = new File("文件路径").如果你本地的JAVA想要访问远程的一个服务器的文件是否存在,就得用如下方法: URL url = new URL(“文件路径:可以是本地服务器...

江苏省17013675384: java 中TCP 怎么设置没次发送的数据包大小?局域网 -
仉宗五味: 这个是无法控制的. 这个是底层TCP协议已经规定好的每次发包的大小. 可以百度下相关的关键字:TCP 包 大小

江苏省17013675384: web 服务器怎么与tcp服务器通讯 -
仉宗五味: 一,网络编程中两个主要的问题 一个是如何准确的定位网络上一台或多台主机,另一个就是找到主机后如何可靠高效的进行数据传输.在TCP/IP协议中IP层主要负责网络主机的定位,数据传输的路由,由IP地址可以唯一地确定Internet上的一台...

江苏省17013675384: IP协议、TCP协议和UDP协议的基本概念和区别 -
仉宗五味: 1网络通讯的协议是开发网络程序的基础.目前最常用的协议是TCP/IP 协议和UDP 协议.而其他的如RMI,SOAP,FTP ,等协议都可以说是构建在这两者之上的. 2 在网络协议的7层模型里,java主要关注的是在传输层 的应用,而对于底层的传输...

江苏省17013675384: android中tcp协议需要导什么包 -
仉宗五味: 不需要任何的jar包,java中自带就java socket 就是基于 TCP 和 UDP协议的 一,网络编程中两个主要的问题 一个是如何准确的定位网络上一台或多台主机,另一个就是找到主机后如何可靠高效的进行数据传输.在TCP/IP协议中IP层主要负责网...

江苏省17013675384: 求教UDP协议发送数据包的大小问题 -
仉宗五味: 100字节是绰绰有余的,据我所了解的UDP,包括java中构造方法 byte[] buffer = new byte[8192]; DatagramPacket dp = new DatagramPacket(buffer, buffer.length); 对此构造方法而言,它并不在乎缓存能有多大而且会很高兴让你创建一个数兆字...

江苏省17013675384: java socket 发送指定时间的TCP数据 -
仉宗五味: 5秒是啥意思?是当字符串信息发送吗?如果是的话,可以把接收到的字符串(或者字节码编码成字符串),然后用模式匹配得出其中的数字5,比如你接收到的字符串为"5秒",模式为"(\\d+)秒",匹配出来的group(1),不就是5了吗

江苏省17013675384: java UDP 传输问题 -
仉宗五味: 每次发送的量少一点就可以了 “TCP/IP规定数据报文大小最多包含65507个,通常主机接收548个字节,但大多数平台能够支持8192字节大小的报文”

江苏省17013675384: TCP通讯服务器程序用什么语言写最好 -
仉宗五味: C语言绝对是适合的,只要你能写出来.C语言运行的效率高,不解释的.java也勉强可以吧.能用C语言写的话,java不做考虑.

江苏省17013675384: C++ TCP传输数据量有上限吗 -
仉宗五味: socket有写缓冲区的,而且网络速度也有限制.这都不一定.

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 星空见康网