Socket for Linux Network Programming (5): Issues and Solutions of TCP flow Protocol

Source: Internet
Author: User

As we have said before, the sender can send data in one K and one K, while the application at the receiver can extract data in two K and two K, of course, it is also possible to extract 3 K or 6 K data at a time, or extract only a few bytes of data at a time. That is to say, the data seen by the application is a whole, or a stream, the data may be split into many data packets for transmission in the underlying communication, but the number of bytes of a data packet is invisible to the application, therefore, the TCP protocol is a stream-oriented protocol, which is also the cause of the packet sticking problem. UDP is a message-oriented protocol. Each UDP segment is a message. The application must extract data in units of messages and cannot extract any bytes of data at a time, this is very different from TCP.

I. The sticking problem can be used to indicate:


Assume that host a sends two data packets m1 and m2 to host B. because the number of bytes received by host B at a time is unknown, there may be four situations,

1. receive two data packets twice, one at a time, without the problem of sticking packets;

2. Two packets are received at a time, which causes the packet sticking problem;

3. The first receives the M1 and M2 parts, and the second receives the M2 part, which has the problem of sticking packets;

4. The first time I received part of M1 and the second time I received another part of M1 and M2, there was a problem of sticking packets;

Of course, there may be more than four actual situations. We can know that communication over the Internet can easily cause packet sticking problems.


Ii. Causes of packet sticking problems

As shown in, there are three main causes: When the write size of the application is greater than the sending buffer size of the set of interfaces, when the TCP segment of the MSS size is performed; when the payload of an Ethernet frame is greater than the MTU for IP sharding, it is easy to produce a packet sticking problem.


3. Solution to the stick package Problem

In essence, it is necessary to maintain the boundary between messages at the application layer.
1. Fixed Length package
2. Add \ r \ n (FTP) to the end of the package)
3. Length of packet header plus package

4. More complex application layer protocols

For entry 2, the disadvantage is that if the message itself contains \ r \ n characters, the boundary of the message is also unclear. Entry 4 is not covered in this article.

For entry 1, we need to send and receive fixed-length packets. Because the TCP protocol is stream-oriented, the returned values of Read and Write calls are usually smaller than the number of bytes specified by the parameter. For read calls (socket flag is blocked), if the receiving buffer contains 20 bytes and the request reads 100 bytes, 20 is returned. For write calls, if the request writes 100 bytes, And the sending buffer has only 20 bytes of free space, the write will be blocked until all 100 bytes are handed over to the sending buffer, however, if the socket file descriptor has the o_nonblock flag, write is not blocked and 20 is returned directly. To avoid interfering with the logic of the main program and ensure the number of bytes requested for reading and writing, we have implemented two packaging functions: readn and writen, as shown below.

C ++ code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
Ssize_t readn (int fd, void * Buf, size_t count)
{
Size_t nleft = count;
Ssize_t nread;
Char * bufp = (char *) BUF;

While (nleft> 0)
{

If (nread = read (FD, bufp, nleft) <0)
{

If (errno = eintr)
Continue;
Return-1;
}

Else if (nread = 0) // the other party closes or has read the EOF
Return count-nleft;

Bufp + = nread;
Nleft-= nread;
}

Return count;
}

Ssize_t writen (int fd, const void * Buf, size_t count)
{
Size_t nleft = count;
Ssize_t nwritten;
Char * bufp = (char *) BUF;

While (nleft> 0)
{

If (nwritten = write (FD, bufp, nleft) <0)
{

If (errno = eintr)
Continue;
Return-1;
}

Else if (nwritten = 0)
Continue;

Bufp + = nwritten;
Nleft-= nwritten;
}

Return count;

}

Note that once these two functions are used in our client/server programs, the size of each read and write operations should be consistent, for example, set to 1024 bytes, but the Fixed Length package cannot read data according to the actual situation, which may cause network congestion. For example, if we only typed a few characters, we still have to send 1024 bytes, this results in a great waste of space.

In this case, entry 3 is a good solution. In fact, it can be regarded as a custom simple application layer protocol. For example, we can customize a package structure.

Struct packet {
Int Len;
Char Buf [1024];
};

First, it receives a fixed 4 bytes, learns the length of the actual data N, and then calls readn to read n characters. This defines the number of data packets and does not need to send fixed-length packets to waste network resources, is a better solution. On the server side, the following changes the do_service function based on the previous fork program:

C ++ code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
Void do_service (INT conn)
{
Struct packet recvbuf;
Int N;
While (1)
{
Memset (& recvbuf, 0, sizeof (recvbuf ));
Int ret = readn (Conn, & recvbuf. Len, 4 );
If (ret =-1)
Err_exit ("read error ");
Else if (Ret <4) // disable the client
{
Printf ("client close \ n ");
Break;
}

N = ntohl (recvbuf. Len );
Ret = readn (Conn, recvbuf. Buf, N );
If (ret =-1)
Err_exit ("read error ");
If (Ret <n) // close the client
{
Printf ("client close \ n ");
Break;
}

Fputs (recvbuf. Buf, stdout );
Writen (Conn, & recvbuf, 4 + n );
}
}

The modification of the client program is similar.

Refer:

Linux C Programming one-stop learning

Chapter 1 TCP/IP details

UNP

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.