Preparations for iOS IM development (4) use of CocoaAsyncSocket and cocoaasyncsocket

Source: Internet
Author: User
Tags starttls

Preparations for iOS IM development (4) use of CocoaAsyncSocket and cocoaasyncsocket

I talked about socket in the previous article. I want to talk about how to work in this article. After all, you can use it.

In my project, CocoaAsyncSocket is used, which is an encapsulation of CFSocket. If you think you can implement encapsulation or use native, I can tell you that it is very tiring. The key is that the project may be handed in when you get it out. This library supports TCP and UDP. There are two options: GCD and RunLoop. Compared with TCP, UDP has a lower reliability and is generally used to transmit videos. A single frame or two is not affected. Here I will talk about the use of TCP, of course, in order to play the performance of the Apple device ox X, I use GCD.

    

Create a socket Singleton

First, we need to maintain a persistent connection. We need to create a global Singleton. Coding of standard Singleton Mode

1 + (instancetype)ShareBaseClient {2     static SocketClient * iSocketCilent;3     static dispatch_once_t onceToken;4     dispatch_once(&onceToken, ^{5         iSocketCilent = [[SocketClient alloc]init];6     });7     return iSocketCilent;8 }
1 # define USE_SECURE_CONNECTION 0 // whether secure connection is required 2 # define USE_CFSTREAM_FOR_TLS 0 // Use old-school CFStream style technique 3 # define MANUALLY_EVALUATE_TRUST 1 // whether manual verification is required -(id) init {7 self = [super init]; 8 // Start the socket stuff. the last one is the thread in which you want to operate. Global 9 asyncSocket = [[GCDAsyncSocket alloc] initWithDelegate: self delegateQueue: dispatch_get_main_queue ()]; 10 NSError * error = nil; 11 uint 16_t port = DefalutPORT; // default port number 12 // connection success/13 // WWW_HOST connection address 14 // 50 s is the set timeout time 15 if (! [AsyncSocket connectToHost: WWW_HOST onPort: port withTimeout: 50366f error: & error]) {16 17 NSLog (@ "Unable to connect to due to invalid configuration: % @", error ); 18 19} else {20 NSLog (@ "Connecting to \" % @ \ "on port % hu... ", WWW_HOST, port); 21} 22 {23 # if USE_SECURE_CONNECTION24 25 # if USE_CFSTREAM_FOR_TLS26 {27 // Use old-school CFStream style technique28 29 NSDictionary * options = @ {30 minutes: @ (YES), 31 GCDAsyncSocketSSLPeerName: CERT_HOST32}; 33 34 DDLogVerbose (@ "Requesting StartTLS with options: \ n % @", options); 35 [asyncSocket startTLS: options]; 36} 37 # elif MANUALLY_EVALUATE_TRUST38 {39 // Use socket: didReceiveTrust: completionHandler: delegate method for manual trust evaluation40 41 NSDictionary * options = @ {42 items: @ (YES ), 43 GCDAsyncSocketSSLPeerName: CERT_HOST44}; 45 46 DDLogVerbose (@ "Requesting StartTLS with options: \ n % @", options); 47 [asyncSocket startTLS: options]; 48} 49 # else50 {51 // Use default trust evaluation, and provide basic security parameters52 53 NSDictionary * options =@{ 54 GCDAsyncSocketSSLPeerName: CERT_HOST55 }; 56 57 DDLogVerbose (@ "Requesting StartTLS with options: \ n % @", options); 58 [asyncSocket startTLS: options]; 59} 60 # endif61 # endif62} 63 return self; 64}

 

Accept packets

If the connection is successful, you can start sending and receiving packets. Here I use the delegate mode, so we need to implement several important proxies:

The first step in connection is to prepare and read data. I use a simple enumeration to identify the area where data is read each time. Generally, the packet first reads the report header and then parses the body. Therefore, after the connection, you must first accept the header.

1 # define READ_HEADER_LINE_BY_LINE 0 2 3 typedef NS_ENUM (long, ReadTagType) {// read data type 4 ReadTagTypehead = 1, // header 5 ReadTagTypebody = 2 // body 6 }; 7 8-(void) socket :( GCDAsyncSocket *) sock didConnectToHost :( NSString *) host port :( UInt16) port 9 {10 NSLog (@ "socket: didConnectToHost: % @ port: % hu ", host, port); 11 12 // whether to read data in a row, here I set 013 # if READ_HEADER_LINE_BY_LINE14 // Now we tell the socket to read the first line of the http response header.15 // As per the http protocol, we know each header line is terminated with a CRLF (carriage return, line feed ). 16 [asyncSocket readDataToData: [GCDAsyncSocket CRLFData] withTimeout:-1.0 tag: 0]; 17 18 # else19 // Now we tell the socket to read the full header for the http response.20 // As per the http protocol, we know the header is terminated with two CRLF's (carriage return, line feed ). 21 // sizeof (protocol_head) the length of a packet header is 22 // ReadTagTypehead first reads the packet header 23 //-1 indicates no timeout time 24 [asyncSocket readDataToLength: sizeof (protocol_head) withTimeout:-1 tag: ReadTagTypehead]; 25 26 # endif27}

After reading the data, the data enters the proxy.

1-(void) socket :( GCDAsyncSocket *) sock didReadData :( NSData *) data withTag :( long) tag {2 3 switch (tag) {4 case ReadTagTypehead: // read head part 5 {6 // After obtaining it, let's take a look at the header 7 // get the command CMD in the head and the length of the next body BodyLength 8 // pass these parameters to a method for processing (in case it is a short title .) 9 10 [self willReadBody: CMD size: BodyLength data: data]; 11} 12 break; 13 case ReadTagTypebody: // read the body section 14 {15 // Add this section, we have obtained complete data. We can send 16 [self haveReadData: data] to the desired location. 17 // then we can read the next packet, or read the header 18 [asyncSocket readDataToLength: sizeof (protocol_head) withTimeout:-1 tag: ReadTagTypehead]; 19} 20 break; 21 default: 22 break; 23} 24} 25 26 // method used for processing the following two are the private method I wrote, not the CocoaAsyncSocket proxy method 27 // prepare to read the body data 28-(void) willReadBody :( int) CMD size :( long) size data :( NSData *) data {29 gCMD = CMD; 30 alldata = [[NSMutableData alloc] initWithData: data]; 31 if (size = 0) {// if it is a short position, the data segment is lost and the next header 32 [self haveReadData: nil]; 33 [asyncSocket readDataToLength: sizeof (protocol_head) withTimeout:-1 tag: ReadTagTypehead]; 34} else {// if not, read the body of the next packet 35 [asyncSocket readDataToLength: dataBufferSize withTimeout: -1 tag: ReadTagTypebody]; 36} 37} 38 39 // callback proxy 40-(void) haveReadData :( NSData *) after data is read *) data {41 // splice the head and body to form the complete data 42 if (data & data. length> 0) 43 [alldata appendData: data]; 44 45 // NSLog (@ "receiveData: % @", alldata); 46 if (alldata. length> 0) {47 // here tell you where you want to process the data. Let him process the data 48} 49 alldata = nil; 50}

In this step, your acceptance of data is complete.

Send packets

[AsyncSocket writeData: data withTimeout:-1.0 tag: 0];

Just one line. No doubt. Call this method after converting your information into NSData. If it succeeds, the proxy is displayed.

-(Void) socket :( GCDAsyncSocket *) sock didWriteDataWithTag :( long) tag;

 

Socket disconnected

Of course, when the socket is disconnected, such as switching the network environment, you need to handle this proxy. You can send a notification to reconnect your application.

- (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err

 

Additional:

When we continuously receive error messages, we need to proactively disconnect the socket.

// Remove the proxy and then disconnect self. asyncSocket. delegate = nil; [self. asyncSocket disconnect];

 

Related Article

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.