Performance optimization tutorial sharing of TCP long connection on Android side

  • 2021-08-21 21:32:45
  • OfStack

Preface

As we all know, there are not many scenarios for implementing TCP long connection on Android, but we are most familiar with the implementation of push and HTTP protocol (OkHttp). This article discusses how to optimize performance when implementing push long connection. The following is only my humble opinion. If there is something wrong, I hope to point out that there is not much to say below. Let's take a look at the detailed introduction.

Push Long Connection

It can be said that most APP can not be separated from the function of push (push), but usually we are mostly connected to the third party SDK (Aurora, push, etc.), because to do a push service, not only the client has to write the corresponding Socket communication code, but also the server is troublesome. To deal with large-scale long-connection service, the message has to be delivered in time, which is too much for one or two servers. Relatively speaking, it will be easier for the client to write the code of Socket communication, but it also needs to deal with some platform-related problems, such as how to keep the push service process alive, how the APP process communicates with the push service process, how to save the power of the mobile phone and how to improve the communication quality under the weak network of the mobile phone. These problems will be analyzed later. Let's take a look at how to optimize the long connection performance of TCP

Points affecting the performance of TCP

The TCP/IP system is too complex, and it is really difficult to fully grasp it. We only analyze several factors that affect the performance of TCP to see if it can be optimized at the Android client

Three-way handshake delay of TCP connection

We know that to establish an TCP connection, we need to go through three handshakes, and the connection is successfully established after three handshakes are successful

When the client requests a new connection, it needs to send a packet with SYN flag to explain these three connection requests to the server When the server accepts the connection request, it will send back a packet with SYN and ACK to the client to show the client that the connection request has been accepted After receiving this packet indicating that the connection request is accepted, the client will send a confirmation message with ACK tag (which may carry service data in this message) to indicate that the connection has been established successfully and the data can be sent

Will the delay caused by establishing the 3-way handshake of TCP connection affect us? In most cases, there is no such thing, only when the amount of data transmitted by HTTP request is relatively small, and then such HTTP request is very frequent, so the delay caused by handshake accounts for a high proportion. In this case, it is necessary to reuse existing connections to reduce the number of connections. Pushing a long connection itself is to keep the stability of the connection, so there is no need to optimize it at this point

Delayed acknowledgement

Because the Internet itself cannot guarantee reliable packet transmission, TCP implements its own acknowledgement mechanism to ensure reliable transmission of data. Receivers who successfully receive TCP packet data need to send back a small acknowledgement packet to the sender. If the sender does not receive this acknowledgement packet within a specified time, he thinks that the data sent before is unsuccessful, and then he will resend the data

However, because the acknowledgement packet is very small, TCP will plug the acknowledgement packet into the data transmitted in the same direction in order to make effective use of the network, and combine it in one transmission. If there is no data transmitted in the same direction within a fixed time, what should I do? Wouldn't it be retransmitted directly? TCP certainly won't allow this situation to be sent. TCP has implemented a delayed acknowledgement algorithm for this situation. If the acknowledgement packet has not been piggybacked at a fixed window time (1 is generally 100 ~ 200 milliseconds), the acknowledgement packet will be sent separately

According to my previous experience in writing TCP long connection, 1 will generally design a service ACK packet mechanism in the application layer, When 1 business data is received, ACK packets of one business layer will be echoed immediately, The ACK packet of this service layer transmits data in the same direction, and the acknowledgement packet will be piggybacked immediately, which will not trigger the delayed acknowledgement algorithm. However, if the message frequency we receive is very high, the ACK packet generated will be very large. Assuming that the ACK packet of the service layer does not need to be so timely, can we combine the ACK packet of the service layer and send it again?

TCP slow start

The performance of TCP connection is also affected by congestion control mechanism. When TCP connection is just connected, it can't send many packets at once. It may be that only one packet can be sent at the beginning of 1, and then two packets can be sent after receiving the confirmation packet, then four packets, and so on. This is the slow start of TCP, and the ability to send data is slowly improving

Since we are writing long connections, this mechanism has little impact on us

Nagle algorithm

Because TCP does not specify the minimum value of each packet, we can transmit 1 byte of data every time, but TCP has a fixed mark and header (at least 40 bytes). If TCP sends a large number of packets containing a small amount of data, the real utilization rate of the network will be very low, and the overall performance of the network will be seriously reduced.

Therefore, TCP uses Nagle algorithm to bind a large amount of TCP data in one packet before sending it, which improves the efficiency of the network. The Nagle algorithm encourages sending full-size packets, and only when all the packets are confirmed can non-full-size packets be sent, otherwise the buffered data will not be sent out until there is enough data to send one full-size packet

What effect does this have when we write TCP long connection? Because our heartbeat packet and ACK packet 1 are all very small, then the server can't receive our heartbeat packet and ACK packet in time, which will produce delay. You can disable Nagle algorithm through the following code


Socket.setTcpNoDelay(true);

TIME_WAIT Accumulation and Port Depletion

This is related to the server, and it has nothing to do with the client, so I won't say it here

Summarize


Related articles: