Solution of TCP unprotected message boundary

Source: Internet
Author: User
Tags int size

As we all know, the TCP protocol is oriented to streaming. Stream-oriented refers to the unprotected message boundary, and if the sender sends the data continuously, the receiving side may receive two or more packets in a single receive action.

So what is protecting the message boundary? refers to the transmission protocol to the data as a separate message on the Internet, the receiving end can only receive independent messages. This means that there is a protection message boundary, and the receiving end can only receive one packet from the sender at a time.

For example, three packets are sent continuously, the size is 1k,2k,4k, the three packets have reached the receiving end of the buffer, if the use of UDP protocol, no matter how much we use the receiving buffer to receive data, you must have three receive action, in order to accept all packets. Using the TCP protocol, as long as the buffer size of the received data set above 7kb, you can receive all packets at a time, that is, only need to receive action once.

So the problem is, because the TCP protocol is streaming, it treats the data as a stream of data, so he doesn't know the boundaries of the message, that is, how separate messages are partitioned. This causes confusion in the message, which means that the data emitted by a Send method is not guaranteed to be read by a recive method. In explaining the buffer, we have already said that the Recive method reads data from the system buffer, so as long as the capacity of the data buffer is large enough, the method does not just receive the first packet's data, it may be all data.

For example, there are two of computers on the network, the client sent the message is: the first time to send ABCDE, the second send 12345, the server can receive the abcde12345, that is, one-time collection, it may be the first time to receive the ABC, the second received the de123, the third time to receive 45.

For this problem, there are generally 3 solutions:

(1) Sending fixed-length messages

(2) Send the message size with the message

(3) Use special tags to distinguish between message intervals

Below we mainly analyze the first two methods:

1. Send fixed-length message
The advantage of this method is that he is very easy, and as long as you specify the length of the good message, there is no missing data, we rewrite a SendMessage method. The code is as follows:

private static int SendMessage (Socket s, byte[] msg)

{
int offset = 0;
int size = Msg. Length;
int dataleft = size;

while (Dataleft > 0)
{

int sent = S.send (msg, offset, socketflags.none);
Offset + + sent;
Dataleft-= sent;

}

return offset;
}

Briefly analyze This function: parameter S is a socket for communication, and MSG is an array of bytes to be sent. This method uses a while loop to check if there is still data not being sent, especially when sending a very large packet, which is more obvious when it is not finished at once. In particular, using sent to record the actual amount of data sent, and recv is the same effect, finally return the total number of actual data sent.

With the Sentmessage function, you also need to design a new Recive method based on the length of the message you specify. The code is as follows:

Private byte[] Recivemessage (Socket s, int size)
{

int offset = 0;
int recv;
int dataleft = size;
byte[] msg = new Byte[size];


while (Dataleft > 0)

{

Receive Message
recv = s.receive (msg, offset, dataleft, 0);
if (recv = 0)

{

Break

}
Offset + + recv;
Dataleft-= recv;

}

return msg;

}

This approach is more appropriate for messages that are not long in length.

2, message length and message sent together

We can do this by using the integer value of the message to represent the actual size of the message, so we want to convert the number of the integer to the byte type. The following is the SendMessage method for sending variable-length messages. The specific code is as follows:

private static int SendMessage (Socket s, byte[] msg)
{

int offset = 0;
int sent;
int size = Msg. Length;
int dataleft = size;
byte[] msgsize = new byte[2];

Converts message size from shaping to a byte type that can be sent
Msgsize = bitconverter.getbytes (size);


Length information for sending messages
Sent = S.send (size);

while (Dataleft > 0)

{

Sent = S.send (msg, offset, dataleft, socketflags.none);

Set offset

Offset + + sent;
Dataleft-= sent;

}

return offset;

}


The following is the Recivevarmessage method for receiving variable-length messages. The code is as follows:

Private byte[] Recivevarmessage (Socket s)
{


int offset = 0;
int recv;
byte[] msgsize = new byte[2];


Converts the message length information of a byte array to an integer
int size = bitconverter.toint16 (msgsize);
int dataleft = size;
byte[] msg = new Byte[size];


Receive length information of 2 byte size
recv = s.receive (msgsize, 0, 2, 0);
while (Dataleft > 0)
{

Receive data
recv = s.receive (msg, offset, dataleft, 0);
if (recv = 0)
{
Break
}
Offset + + recv;
Dataleft-= recv;

}

return msg;

}

References: http://aksnzhy.javaeye.com/blog/789049

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.