关于socket粘包问题_第1页
关于socket粘包问题_第2页
关于socket粘包问题_第3页
关于socket粘包问题_第4页
关于socket粘包问题_第5页
已阅读5页,还剩3页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

关于 Socket 粘包问题 2010-11-24 来自:CSDN 字体大小:【大 中 小】 摘要:这两天看 csdn 有一些关于 socket 粘包,socket 缓冲区设置的问题,发现自己不是很 清楚,所以查资料了解记录一下 这两天看 csdn 有一些关于 socket 粘包,socket 缓冲区设置的问题,发现自己不是很清楚 ,所以查资料了解记录一下: 一两个简单概念长连接与短连接: 1.长连接 Client 方与 Server 方先建立通讯连接,连接建立后不断开, 然后再进行报文发送和 接收。 2.短连接 Client 方与 Server 每进行一次报文收发交易时才进行通讯连接,交易完毕后立即断 开连接。此种方式常用于一点对多点 通讯,比如多个 Client 连接一个 Server. 二 什么时候需要考虑粘包问题? 1:如果利用 tcp 每次发送数据,就与对方建立连接,然后双方发送完一段数据后,就关闭 连接,这样就不会出现粘包问题(因为只有一种包结构,类似于 http 协议)。关闭连接主 要要双方都发送 close 连接(参考 tcp 关闭协议)。如:A 需要发送一段字符串给 B,那么 A 与 B 建立连接,然后发送双方都默认好的协议字符如“hello give me sth abour yourse lf“,然后 B 收到报文后,就将缓冲区数据接收,然后关闭连接,这样粘包问题不用考虑到 ,因为大家都知道是发送一段字符。 2:如果发送数据无结构,如文件传输,这样发送方只管发送,接收方只管接收存储就 ok ,也不用考虑粘包 3:如果双方建立连接,需要在连接后一段时间内发送不同结构数据,如连接后,有好几种 结构: 1)“hello give me sth abour yourself“ 2)“Dont give me sth abour yourself“ 那这样的话,如果发送方连续发送这个两个包出去,接收方一次接收可能会是“hello g ive me sth abour yourselfDont give me sth abour yourself“ 这样接收方就傻了,到 底是要干嘛?不知道,因为协议没有规定这么诡异的字符串,所以要处理把它分包,怎么 分也需要双方组织一个比较好的包结构,所以一般可能会在头加一个数据长度之类的包, 以确保接收。 三 粘包出现原因:在流传输中出现,UDP 不会出现粘包,因为它有消息边界(参考 Windows 网络编程) 1 发送端需要等缓冲区满才发送出去,造成粘包 2 接收方不及时接收缓冲区的包,造成多个包接收 解决办法: 为了避免粘包现象,可采取以下几种措施。一是对于发送方引起的粘包现象,用户可通过 编程设置来避免,TCP 提供了强制数据立即传送的操作指令 push,TCP 软件收到该操作指 令后,就立即将本段数据发送出去,而不必等待发送缓冲区满;二是对于接收方引起的粘 包,则可通过优化程序设计、精简接收进程工作量、提高接收进程优先级等措施,使其及 时接收数据,从而尽量避免出现粘包现象;三是由接收方控制,将一包数据按结构字段, 人为控制分多次接收,然后合并,通过这种手段来避免粘包。 以上提到的三种措施,都有其不足之处。第一种编程设置方法虽然可以避免发送方引起的 粘包,但它关闭了优化算法,降低了网络发送效率,影响应用程序的性能,一般不建议使 用。第二种方法只能减少出现粘包的可能性,但并不能完全避免粘包,当发送频率较高时 ,或由于网络突发可能使某个时间段数据包到达接收方较快,接收方还是有可能来不及接 收,从而导致粘包。第三种方法虽然避免了粘包,但应用程序的效率较低,对实时应用的 场合不适合。 相关文章截取: 一个包没有固定长度,以太网限制在 461500 字节,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_ERR OR 时,才标志着有错误。但对于 UDP,你不要写循环发送,否则将给你的接收带来极大的 麻烦。所以 UDP 需要用 SetSockOpt 来改变 Socket 内部 Buffer 的大小,以能容纳你的发包 。明确一点,TCP 作为流,发包是不会整包到达的,而是源源不断的到,那接收方就必须 组包。而 UDP 作为消息或数据报,它一定是整包到达接收方。 2、关于接收,一般的发包都有包边界,首要的就是你这个包的长度要让接收方知道,于是 就有个包头信息,对于 TCP,接收方先收这个包头信息,然后再收包数据。一次收齐整个 包也可以,可要对结果是否收齐进行验证。这也就完成了组包过程。UDP,那你只能整包接 收了。要是你提供的接收 Buffer 过小,TCP 将返回实际接收的长度,余下的还可以收,而 UDP 不同的是,余下的数据被丢弃并返回 WSAEMSGSIZE 错误。注意 TCP,要是你提供的 Buf fer 佷大,那么可能收到的就是多个发包,你必须分离它们,还有就是当 Buffer 太小,而 一次收不完 Socket 内部的数据,那么 Socket 接收事件(OnReceive),可能不会再触发,使 用事件方式进行接收时,密切注意这点。这些特性就是体现了流和数据包的区别。 相关参考文章: 解决 TCP 网络传输“粘包”问题 当前在网络传输应用中,广泛采用的是 TCP/IP 通信协议及其标准的 socket 应用开发编程 接口(API)。TCP/IP 传输层有两个并列的协议:TCP 和 UDP。其中 TCP(transport contr ol protocol,传输控制协议)是面向连接的,提供高可靠性服务。UDP(user datagram p rotocol,用户数据报协议)是无连接的,提供高效率服务。在实际工程应用中,对可靠性 和效率的选择取决于应用的环境和需求。一般情况下,普通数据的网络传输采用高效率的 udp,重要数据的网络传输采用高可靠性的 TCP。 在应用开发过程中,笔者发现基于 TCP 网络传输的应用程序有时会出现粘包现象(即发送 方发送的若干包数据到接收方接收时粘成一包)。针对这种情况,我们进行了专题研究与 实验。本文重点分析了 TCP 网络粘包问题,并结合实验结果提出了解决该问题的对策和方 法,供有关工程技术人员参考。 一、TCP 协议简介 TCP 是一个面向连接的传输层协议,虽然 TCP 不属于 iso 制定的协议集,但由于其在 商业界和工业界的成功应用,它已成为事实上的网络标准,广泛应用于各种网络主机间的 通信。 作为一个面向连接的传输层协议,TCP 的目标是为用户提供可靠的端到端连接,保证 信息有序无误的传输。它除了提供基本的数据传输功能外,还为保证可靠性采用了数据编 号、校验和计算、数据确认等一系列措施。它对传送的每个数据字节都进行编号,并请求 接收方回传确认信息(ack)。发送方如果在规定的时间内没有收到数据确认,就重传该数 据。数据编号使接收方能够处理数据的失序和重复问题。数据误码问题通过在每个传输的 数据段中增加校验和予以解决,接收方在接收到数据后检查校验和,若校验和有误,则丢 弃该有误码的数据段,并要求发送方重传。流量控制也是保证可靠性的一个重要措施,若 无流控,可能会因接收缓冲区溢出而丢失大量数据,导致许多重传,造成网络拥塞恶性循 环。TCP 采用可变窗口进行流量控制,由接收方控制发送方发送的数据量。 TCP 为用户提供了高可靠性的网络传输服务,但可靠性保障措施也影响了传输效率。 因此,在实际工程应用中,只有关键数据的传输才采用 TCP,而普通数据的传输一般采用 高效率的 udp。 二、粘包问题分析与对策 TCP 粘包是指发送方发送的若干包数据到接收方接收时粘成一包,从接收缓冲区看, 后一包数据的头紧接着前一包数据的尾。 出现粘包现象的原因是多方面的,它既可能由发送方造成,也可能由接收方造成。发 送方引起的粘包是由 TCP 协议本身造成的,TCP 为提高传输效率,发送方往往要收集到足 够多的数据后才发送一包数据。若连续几次发送的数据都很少,通常 TCP 会根据优化算法 把这些数据合成一包后一次发送出去,这样接收方就收到了粘包数据。接收方引起的粘包 是由于接收方用户进程不及时接收数据,从而导致粘包现象。这是因为接收方先把收到的 数据放在系统接收缓冲区,用户进程从该缓冲区取数据,若下一包数据到达时前一包数据 尚未被用户进程取走,则下一包数据放到系统接收缓冲区时就接到前一包数据之后,而用 户进程根据预先设定的缓冲区大小从系统接收缓冲区取数据,这样就一次取到了多包数据 (图 1 所示)。 图 1 图 2 图 3 粘包情况有两种,一种是粘在一起的包都是完整的数据包(图 1、图 2 所示),另一 种情况是粘在一起的包有不完整的包(图 3 所示),此处假设用户接收缓冲区长度为 m 个 字节。 不是所有的粘包现象都需要处理,若传输的数据为不带结构的连续流数据(如文件传 输),则不必把粘连的包分开(简称分包)。但在实际工程应用中,传输的数据一般为带 结构的数据,这时就需要做分包处理。 在处理定长结构数据的粘包问题时,分包算法比较简单;在处理不定长结构数据的粘 包问题时,分包算法就比较复杂。特别是如图 3 所示的粘包情况,由于一包数据内容被分 在了两个连续的接收包中,处理起来难度较大。实际工程应用中应尽量避免出现粘包现象 。 为了避免粘包现象,可采取以下几种措施。一是对于发送方引起的粘包现象,用户可 通过编程设置来避免,TCP 提供了强制数据立即传送的操作指令 push,TCP 软件收到该操 作指令后,就立即将本段数据发送出去,而不必等待发送缓冲区满;二是对于接收方引起 的粘包,则可通过优化程序设计、精简接收进程工作量、提高接收进程优先级等措施,使 其及时接收数据,从而尽量避免出现粘包现象;三是由接收方控制,将一包数据按结构字 段,人为控制分多次接收,然后合并,通过这种手段来避免粘包。 以上提到的三种措施,都有其不足之处。第一种编程设置方法虽然可以避免发送方引 起的粘包,但它关闭了优化算法,降低了网络发送效率,影响应用程序的性能,一般不建 议使用。第二种方法只能减少出现粘包的可能性,但并不能完全避免粘包,当发送频率较 高时,或由于网络突发可能使某个时间段数据包到达接收方较快,接收方还是有可能来不 及接收,从而导致粘包。第三种方法虽然避免了粘包,但应用程序的效率较低,对实时应 用的场合不适合。 一种比较周全的对策是:接收方创建一预处理线程,对接收到的数据包进行预处理, 将粘连的包分开。对这种方法我们进行了实验,证明是高效可行的。 三、编程与实现 1实现框架 实验网络通信程序采用 TCP/IP 协议的 socket api 编程实现。socket 是面向客户机/ 服务器模型的。TCP 实现框架如图 4 所示。 图 4 2实验硬件环境: 服务器:pentium 350 微机 客户机:pentium 166 微机 网络平台:由 10 兆共享式 hub 连接而成的局域网 3实验软件环境: 操作系统:windows 98 编程语言:visual c+ 5.0 4主要线程 编程采用多线程方式,服务器端共有两个线程:发送数据线程、发送统计显示线程。 客户端共有三个线程:接收数据线程、接收预处理粘包线程、接收统计显示线程。其中, 发送和接收线程优先级设为 thread_priority_time_critical(最高优先级),预处理线 程优先级为 thread_priority_above_normal(高于普通优先级),显示线程优先级为 thre ad_priority_normal(普通优先级)。 实验发送数据的数据结构如图 5 所示: 图 5 5分包算法 针对三种不同的粘包现象,分包算法分别采取了相应的解决办法。其基本思路是首先 将待处理的接收数据流(长度设为 m)强行转换成预定的结构数据形式,并从中取出结构 数据长度字段,即图 5 中的 n,而后根据 n 计算得到第一包数据长度。 1)若 nm,则表明

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论