AsyncSocket persistent connection stick package solution, asyncsocket
Long connections are used in the project to communicate with the server. Therefore, our protocolThe first two bytes are the data length.To distinguish data packets
App data can be transmitted in two ways:
1. The app actively requests the required data;
2. The app asynchronously receives push messages from the server, that is, the app has no request, and the server actively sends data to the app client;
During the entire app running, the data is transmitted over the same connection, so the following problems may occur:
1. The server's data transmission is too fast, and the problem of sticking packets occurs, for example
1.1 The server sends multiple push messages at a time;
1.2 The network is unstable. The client sends multiple requests to the client to receive all replies at a time;
2. For a client request message, the server's response packet data is too large and needs to be split to the IP layer. Therefore, the client will receive the complete data several times;
First, we need to introduce the following four methods:
/**
** Instance method
** After this method is called, when the socket receives available bytes in the buffer zone, the onSocket: didReadData: withTag: Delegate method is triggered. In this case, the received data will encounter the problem mentioned above.
*/
-(Void) readDataWithTimeout :( NSTimeInterval) timeout tag :( long) tag;
/**
** Instance method
** After this method is called, when the socket receives available bytes with a length in the buffer zone, the onSocket: didReadData: withTag: Delegate method is triggered. At this time, data of a fixed length is received, this fixed length is the value given by length. When the length is greater than the length of the received buffer data, it will wait, the call of the preceding delegate method is triggered only when the length data is received.
*/
-(Void) readDataToLength :( NSUInteger) length withTimeout :( NSTimeInterval) timeout tag :( long) tag;
/**
** Instance method
** This method is the same as above. It only has a few more parameters. buffer is the place where you write the received data, and offset is the offset location in the buffer.
*/
-(Void) readDataToLength :( NSUInteger) length
WithTimeout :( NSTimeInterval) timeout
Buffer :( NSMutableData *) buffer
BufferOffset :( NSUInteger) offset
Tag :( long) tag;
/**
** Delegate Method
** As mentioned above
*/
-(Void) onSocket :( AsyncSocket *) sock didReadData :( NSData *) _ data withTag :( long) tag;
Solution:
After each request is sent, the client receives only two bytes in length, as shown below:
[sendSocket readDataToLength:2 withTimeout:set.timeout tag:tag];[sendSocket writeData:data withTimeout:set.timeout tag:tag];
Then, when the available bytes reach the socket receiving buffer, the following delegate method is triggered. We will do the following processing in it, which not only solves the problem of sticking packets, but also solves the problem of excessive data, receive complete questions multiple times;
- (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)_data withTag:(long)tag{ SettingData* set = [SettingData shareSettingData]; if (respondData == nil) { respondData = [[NSMutableData alloc]init]; respondDataLen = [RequestUnit respondMessageLengthWithData:_data]; [sock readDataToLength:respondDataLen withTimeout:set.timeout tag:tag]; return; } [respondData appendData:[RequestUnit respondBytesToUTF8Data:_data]]; [self parserData:respondData withTag:tag];}
How does AsyncSocket splice packets? Come on!
Can I use NSMutableData? NSMutableData * data = [[NSMutableData alloc] ini]; [data appendData: xxx]; but do you have to differentiate between start and end to view the original post>