第一个需要讨论的大概就是粘包问题了。因为这个是TCP的个性问题,UDP通信时不存在这个问题的。首先看一下什么叫粘包:
客户端采取与服务器的长连接方式建立通信(Open-Write/Read-Write/Read-……-Write/Read-Close)。即建立连接之后进行多次读写操作,最后才关闭。而且不是文件传输,而是数据结构的传输(文件传输发生粘包与没发生粘包都不会影响结果,反正都是字节流的按顺序写入本地文件)。举个例子来说明一下吧:
两种数据结构:{give me something} {don't give me anything}则粘包是则是接受到{give me something don't give me anything} 这个算是让服务器傻眼了,没见过这么诡异的数据结构,不知道怎么处理了。
|
上面的例子是转的网上的
来分析一下之所以发生粘包的原因吧,其实也就是为什么TCP会发生,但是UDP却不会发生的原因:TCP是面向连接流式无边界的传输方式。当传输通道建立之后,则数据流就像水一样流过来,其中没有数据边界的概念,包随便多大,因而会出现多个包最后粘成一个大包。当然这个是TCP的原因,还有就是缓冲区机制的问题,发送端在默认状况下是需要等到发送去满才发送出去,故而适当使用push刷缓冲区也可减少粘包的现象,还有就是接受缓冲区处理不及时,没有做到来一个包立马处理完这个包。
所以解决的思路大约如下:
-
对于发送方引起的粘包现象,用户可通过编程设置来避免,
TCP
提供了强制数据立即传送的操作指令
push
,
TCP
软件收到该操作指令后,就立即将本段数据发送出去,而不必等待发送缓冲区满。此种方法关闭了优化算法,降低了网络发送效率,影响应用程序的性能。而且并不能保证
100%
不发生粘包现象。
-
对于接收方引起的粘包,则可通过优化程序设计、精简接收进程工作量、提高接收进程优先级等措施,使其及时接收数据,从而尽量避免出现粘包现象。该种思路对于接收方的程序算法结构要求较高,而且可靠性不高,因为网络通信中的并发等现象大量存在,很难真的能完全即使处理接受缓冲区而不发生粘包。
-
由接收方控制,将一包数据按结构字段,人为控制分多次接收,然后合并,通过这种手段来避免粘包。该思路的问题就更大了,应用程序效率被降低太多。而且我实在不认为这个真能不发生粘包,虽然包变小了,但是并发情况的存在并不能保证接收方有足够的间隙去处理包。
-
预定义数据结构,单线程。字节流前面先加上包头标志位,包头中包含该包的数据长度,这样在读取的时候可按字节读取。这样可有效控制粘包问题。并可以成功避免残包的问题,且不会发生连锁反应,一个坏包的出现不会影响下一个包的正常读取。如{##Length##DataStram}。该中解决方案的优点是可以保证通信的100%准确,缺点是影响程序性能,因为按字节读取包,必定会影响程序的效率。
-
改进:预定义数据结构,单线程。但是不是按字节。查看头标志位,读取包长度,查看缓冲区内包长度,两者相等,则直接读取。如果缓冲区内可读字节数大于标志位描述的包长度,则按照标志位描述的包长度读取数据,如果缓冲区内刻度字节数小于标志位描述的包长度,则线程睡眠,等下一个数据包的到来。
-
预定义数据结构,多线程。服务器端与客户端都是多线程工作,客户端为三个主要线程:发送线程、读取线程与解析线程。服务器端为四个主要线程:监听主线程、接收、读取、解析。按照第五种的思路,拿到数据包之后直接扔给解析线程,解析线程负责数据解析以及最终结果的回调。此处比第五种多的思路就是一个多线程,从而可以很大幅度提升程序的性能。
预定义数据结构示意图:
分享到:
相关推荐
在TCP/IP通信中,"粘包"问题是一个常见的现象,特别是在C#等编程语言中进行TCP编程时。TCP粘包是指发送方发送的多个数据包在接收方接收时被合并成一个大包,使得接收方无法正确区分各个独立的数据包。这种问题通常是...
在计算机网络编程中,"粘包"问题是一个常见的现象,特别是在TCP协议中。TCP是一种面向连接的、可靠的传输层协议,它为了提高效率,会尽可能地将数据进行批量发送,而不是每次只发送一个数据包。这在某些情况下会导致...
本程序使用设计良好的函数,使得应用层不需要考虑网络消息是如何被接受和发送的,重点演示了如何优雅地处理TCP/IP网络数据粘包和丢包的刺手问题,你只要调用相应的函数就可以了。你只需要定义自己的协议头和消息...
总结来说,QT提供的网络编程接口和C++的数据流操作为我们提供了一种有效解决TCP粘包和拆包问题的途径。通过自定义协议,结合序列化和反序列化技术,我们可以在TCP通信中实现可靠的数据交换,确保应用的正常运行。在...
Socket编程在TCP网络通信中是一项基础且重要的技术,而TCP粘包问题则是开发者在实际应用中经常遇到的一个挑战。TCP(传输控制协议)是面向连接的、可靠的传输协议,它在保证数据正确传输的同时,也可能因为其特性...
在计算机网络编程中,TCP(传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议。然而,TCP本身并不保证数据包的边界,也就是说,多个小的数据包可能会被合并成一个大的数据包发送,或者一个大的...
**粘包问题**指的是在网络传输中,由于TCP协议的特性,发送方连续发送的多个数据包在接收方看来可能被合并成了一个数据包,从而导致原本应该独立的消息被粘合在一起。 **拆包问题**则是指发送方的一个完整数据包在...
在TCP协议中,由于其...总的来说,TCP粘包和拆包是网络编程中常见的挑战,但通过合理的设计和编程技巧,我们可以有效地避免这些问题,确保数据的准确传输。在实际项目中,需要根据具体需求和场景选择合适的解决方案。
在IT行业中,网络编程是不可或缺的一部分,特别是在分布式系统和实时通信中。TCP(Transmission Control Protocol)作为传输层的协议,以其可靠性和面向连接的特点被广泛使用。然而,TCP在处理数据传输时,可能会...
Socket通信是计算机网络编程中的重要组成部分,主要用于实现进程间的通信,尤其在分布式系统和互联网应用中扮演着核心角色。在TCP/IP协议栈中,Socket接口提供了应用层与传输层之间的接口,使得应用程序能够利用TCP...
在TCP/IP通信中,"粘包...总之,解决GOLANG中的SOCKET通信粘包问题,关键在于定义清晰的协议格式,并在客户端和服务器端正确地打包和解包数据。通过这种方式,即使在TCP的流式传输中,也能确保数据的完整性和准确性。
QT/C++ TCP多线程客户端的设计是为了解决在高并发场景下可靠地收发数据的问题。TCP(传输控制协议)是一种面向连接的、...总之,这个QT/C++ TCP多线程客户端的设计体现了高并发环境下对TCP通信的高效管理和可靠性保证。
你可以通过研究这些代码来加深对C# Socket编程的理解,包括异步通信的实现、TCP粘包问题的解决方法,以及如何优化网络通信性能。在实际开发中,结合这些知识,你将能构建出高效、可靠的网络应用程序。
在计算机网络编程中,TCP(传输控制协议)是一种面向连接的、可靠的传输协议,它确保数据包按顺序无损地到达目的地。然而,TCP协议在某些...只要正确地处理数据包的头部和数据体,就能确保TCP通信的可靠性和有效性。
在Qt框架下实现多线程TCP通信是一种常见且高效的方法,尤其在处理实时性要求高、数据量大的网络应用中。以下将详细讲解Qt中如何进行多线程TCP通信,以及涉及的关键知识点。 首先,标题"qt 中 多线程tcp通信"表明...
我们可以采用.NET自带的类库编写,但是由于这些类库只是基础的设施,需要自行处理比如断线重连、网络波动、tcp粘包等等问题,并且还要考虑稳定性和吞吐等因素,所以可以调用一些类库。 这里介绍一个比较稳定可靠,又...
Linux网络编程中的Socket接口是应用程序进行网络通信的主要方式,尤其在TCP/IP协议栈中,TCP流协议因其特性可能会引发“粘包”问题。TCP是一种面向流的协议,它不保证数据包的边界,而是将数据视为一个连续的字节流...