简体   繁体   English

防止TCP上的拆分数据包

[英]Preventing split packets over TCP

I am writing a program that transfers files over the network using TCP sockets. 我正在编写一个程序,使用TCP套接字通过网络传输文件。

Now I noticed that when I send a packet in size for example 1024 bytes, I get them split on the other side. 现在我注意到,当我发送一个大小为1024字节的数据包时,我会将它们拆分到另一端。

By "split" I mean I get some packets as if they were a part of a whole packet. 通过“拆分”我的意思是我得到一些数据包就好像它们是整个数据包的一部分。

I tried to reduce the packet size and the algorithm worked, when the packet size was immensely small (about 30 bytes per packet) thus the file transferred very slowly. 当数据包大小非常小(每个数据包大约30个字节)时,我试图减小数据包大小和算法工作,因此文件传输速度非常慢。

Is there anything I can do in order to prevent the splitting? 有什么我可以做的,以防止分裂?

SOLVED:i switched the connection to be over UDP and since UDP is packet bounded it worked 已解决:我将连接切换为UDP,因为UDP是数据包限制,所以它有效

There is not such thing in TCP. TCP中没有这样的东西。

TCP is a stream, what you write is what you get at the other end. TCP是一个流,你写的就是你在另一端获得的。 This does not mean you get it the way it was written; 这并不意味着你按照它的方式得到它; TCP may break or group packets in order to do the jobs as effectively as possible. TCP可能会破坏或分组数据包,以便尽可能有效地完成工作。 You can send 8 mega bytes packet in one write and TCP can break down into 10, 100 or 1000 packets, what you need to know is that at the other end you will get exactly 8 mega bytes no more no less. 您可以在一次写入中发送8兆字节数据包,TCP可以分解为10,100或1000个数据包,您需要知道的是,在另一端,您将获得正好8兆字节不再少。

In order to do a file transfer effectively you need to tell the receiver how many bytes you are going to send. 为了有效地进行文件传输,您需要告诉接收器您要发送多少字节。 The receiver may read it in one chunk or in 100 chunks but must keep track of the data it reads and how many bytes to read. 接收器可以在一个块或100个块中读取它,但必须跟踪它读取的数据和要读取的字节数。

Because TCP is stream oriented, TCP will not transfer information of 'packet boundaries', like UDP and SCTP. 由于TCP是面向流的,因此TCP不会传输“数据包边界”的信息,如UDP和SCTP。

So you must add information of packet boundaries to TCP payload, if it is not there already. 因此,您必须将数据包边界的信息添加到TCP有效负载(如果尚未存在)。 There are several ways to do it: 有几种方法可以做到:

  • You can use a length field for indicating how many bytes the following packet contains. 您可以使用长度字段来指示后续数据包包含的字节数。
  • Or there could be a reserved symbol for separating different packets. 或者可以存在用于分离不同分组的保留符号。

In all ways, receiver must read TCP input stream again, if complete packet is not received. 在所有方面,如果没有收到完整的数据包,接收器必须再次读取TCP输入流。

You can control the TCP maximum segment size in some socket implementations. 您可以在某些套接字实现中控制TCP最大段大小。 If you set it low enough, you can make the segment fit inside a single packet. 如果将其设置得足够低,则可以使段适合单个数据包。 The BSD Sockets API, which influenced almost every other implementation, has a setsockopt() function that lets you set various options on the socket. BSD套接字API几乎影响了所有其他实现,它有一个setsockopt()函数,可以让你在套接字上设置各种选项。 One of them, TCP_MAXSEG , controls the maximum segment size. 其中之一TCP_MAXSEG控制最大段大小。

Unfortunately for you, the standard Java Socket class doesn't support this particular option. 不幸的是,标准的Java Socket类不支持这个特定的选项。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM