Recently, the ios client of car tracking has been doing socket communication intermittently. So far, the project has adjusted data transmission and can send and receive data with the server normally, which has solved the most important part of the project. When I first took over this project, I felt it was a challenge. The biggest difference was that the network data requests in the project were not simple GET and POST, the so-called short connection. The project needed to maintain the real-time connection between the customer terminal and the server, and the long connection based on TCP. Let me start by talking about some of the more confusing and intractable problems I encountered

  • 1. Socket communication I must first of all use a third-party open source framework, I do not have the strength to write from the bottom, and I and the server transmissionNSDataType of data, what exactly is it? How do I parse it?
  • 2. This is also the most difficult problem I have encountered, the server is usedJAVATo be written in the codeGB2312, how can transcoding canUTF-8Type?

This article mainly starts from these two questions, summarizes and shares my recent work achievements: 1. H and GCDAsyncsocket. h. What I need is a long connection, so I need the header file gcdAsyncsocket. h. Creating a connection server is simple

// Declare a socket member variable
GCDAsyncSocket *Socket;
// Create a socket object in viewDidLoad
 GCDAsyncSocket *socket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)];
    self.Socket = socket;
    // Connect to the server
    NSError *error = nil;
    [privateSocket connectToHost:p_host onPort:p_port error:&error];
    if(! error){ NSLog(@"Local socket connected to server socket successfully");
    }else
    {
        NSLog(@"error--%@",error);
    }

// All business processing of receiving data is mainly implemented in its proxy methods
// Successful connection -- callback as long as successful connection
- (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port
{

}
// Disconnect from the server
- (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err
{

}

// Called when a socket has completed writing the requested data
// Call back to the server on success
- (void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag
{
}
// Receive data from the server
- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag
{
}Copy the code

The proxy method above is a common proxy method for socket communication, in addition, it is my leader’s wu work, let me open two child thread 1. 2 make sure that the server disconnects reconnect to the server to send a particular message keep connection, to the first question I personally feel that can operate in the agent approach, it is not necessary to open a child thread, but Wu Gong request, I will act in accordance with the requirements, has been considered at the time, how to start a child thread let him die? I thought of NSRunLoop, but I don’t know how to operate it. I did a search on Baidu, but I didn’t find the answer. Readers who know can provide a method, I’m very grateful. Let’s talk about my method. Let’s look at the code

- (void)startAsync{
 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) ^ {[NSThread currentThread].name = @"P_mainSendMessage";

        while(TRUE)
        {
            sleep(1);
         // Send data here
    });
}Copy the code

Do you think this method is very simple, do an infinite loop in the thread does not solve the problem. So NSData, what is it

NSData and its mutable subclass NSMutableData provide data objects, object-oriented wrappers for byte buffers. Data objects let simple allocated buffers (that is, data with no embedded pointers) take on the behavior of Foundation objects.

It’s simply a byte with a length, and that’s what we need to do when we receive data

    char Buf[16384];
    char *by = (char *)[data bytes];
    memcpy(&Buf[0], by .data.length);Copy the code

Then we need to manipulate the Buf[16384] character array, rather than simply receiving data from the server and converting it to a string. For example:

NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];Copy the code

Simple string, send a string so simple, I receive here is the custom of a communication protocol TCP connection, send me a bunch of things, including checking, etc., so we don’t receive into a simple string is ok, we have to convert a character array, and then after implement of a series of verification, extraction operation. For the first question and how to send to the server, due to the coding problem, I will explain in the second question. 2. Coding problems. Generally, JAVA servers including Chinese characters will adopt GB2312 encoding mode, while utF-8 encoding mode is required for normal display on mobile terminals, just as in HTML language

<html>
  <head>
  </head>
  <body>
  <div>Hahaha hahaha</div>
  </body>
</html>Copy the code

We need to transcode into UTF-8 on the mobile terminal. In fact, transcoding is not difficult, baidu will appear a lot of, I looked up about two versions version one

NSStringEncoding enc = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000);
NSString *reStr = [[NSString alloc] initWithData:data encoding:enc];Copy the code

Version 2

  NSStringEncoding enc = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000);
  NSString *reStr = [[NSString alloc] initWithData:data encoding:enc];
  NSData *reData = [reStr dataUsingEncoding:NSUTF8StringEncoding];Copy the code

This requires us to judge where to transcode, I began to consider the version of the second, such as I received the data unified transfer, and then just, the following process unchanged, but! But!!!! When contains Chinese characters and then turn it back when the data is empty, I consult qq friends, they offer like this way of the above two versions transcoding is empty, this time I am still continue to find ways, to find ah find, or empty, so is a transport protocol service constraints, or copy to Buf array, scope out the problem? Is this method, I stopped looking for the key, perfectly solves the problem by communication, this let me know, what went wrong don’t blindly to do, if you think your ability is only do here, by this time you ought to have a communication with others, so also is advantageous to the development of the project, if the project is tight, the best early communication, And colleagues as long as not busy will be willing to help!! Because they are also afraid of one day their own problems can not be solved!

    NSStringEncoding enc = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000);
    NSLog(@"-- -- -- -- -- -- -- % @",[NSString stringWithCString:charBuf encoding:enc]);Copy the code

This method is to transcode a char string so that you can store the characters and display them. Finally, a word about sending data

- (void)writeData:(NSData *)data withTimeout:(NSTimeInterval)timeout tag:(long)tag;Copy the code

This is also sending data, so we need to wrap char as NSData

[Socket writeData:[NSData dataWithBytes:p_charSeData[p_intSeSequence] length:p_intSeCount[p_intSeSequence][1]] withTimeout:-1 tag:0];Copy the code

Remember to transcode if the message contains Chinese characters, as mentioned above. The above is the establishment of the initial communication mode, the channel for sending and receiving data has been all through, I hope to do socket communication friends help, in fact, there are many details to pay attention to, such as receiving data proxy method, and then receive data, will only accept once, can not receive continuously, need to add in the proxy method

[Socket readDataWithTimeout:- 1 tag:0];Copy the code

In this way, the data can be continuously received. You can pay attention to the details. Welcome to point out the wrong place, after all, I started to do this piece, many places are not thoughtful, please understand, welcome to leave a message, we will answer.