iOS learning socket using a simple tutorial-asyncsocket

Source: Internet
Author: User

If need in the project like QQ to do instant communication, must use socket communication, I also just learn, share, there is nothing wrong place hope everybody correct

iOS native socket is not very intuitive to use, so I use asyncsocket this third-party library, the socket is better, just as if there is no out-of-band transmission (Out-of-band) If your server needs to send out out-of-band data, you might want to do something else.

Environment

Download the Asyncsockethttps://github.com/robbiehanson/cocoaasyncsocket class library, place the Runloop folder under AsyncSocket.h, ASYNCSOCKET.M, AsyncUdpSocket.h, ASYNCUDPSOCKET.M files are copied to your own project

Add Cfnetwork.framework, in the file header using the socket

#import <sys/socket.h> #import <netinet/in.h> #import <arpa/inet.h> #import <unistd.h>

Use

1. Socket connection

Real-time communication is the most important feature is realtime, the basic sense is not delayed or dropped, so the connection to the socket must be monitored and detected, when disconnected, reconnect, if the user exits the login, to the socket manually shut down, or the server will cause a certain load.

In general, a user (for iOS, our project) can have only one socket connected, so the socket variable must be global, here you can consider using a singleton or appdelegate for data sharing, this article uses a single case. If a connected socket object is connected again, it throws an exception (no connection to the connected socket) crashes, so the connection state of the socket object is judged before connecting to the socket.

Using the socket for Instant messaging There is also a necessary operation, that is, sending a heartbeat packet to the server, sending long connection instructions to the server at intervals (instructions are not unique, specified by the server, including sending messages using the socket, sending data and formats are specified by the server), If you do not receive a return message from the server, Asyncsocket will get the message of the lost connection, and we can reconnect in the lost connection callback method.

First create a singleton, named Singleton

Singleton.h

Singleton.h#import "AsyncSocket.h" #define Define_shared_instance_using_block (BLOCK) \static dispatch_once_t Oncetoken = 0; __strong static id sharedinstance = NIL; \dispatch_once (&oncetoken, ^{sharedinstance = block ();}); \return sharedinstance; \ @interface singleton:nsobject+ (Singleton *) sharedinstance; @end

Singleton.m

+ (Singleton *) sharedinstance{static Singleton *sharedinstace = nil;static dispatch_once_t oncetoken;dispatch_once ( &oncetoken, ^{sharedinstace = [[Self alloc] init];}); return sharedinstace;}

Such a single example is created.

The life socket variable in the. h file

@property (nonatomic, strong) Asyncsocket *socket;   [Email protected] (nonatomic, copy) NSString *sockethost;    socket [email protected] (nonatomic, assign) UInt16 Socketport; Socket's Prot

Here is 连接 , 心跳 ,,失去连接后重连

Connection (long Connection)

Declare the method in the. h file, and declare the proxy<AsyncSocketDelegate>

-(void) socketconnecthost;//socket connection

Implemented in. m, the host and port are specified by the server when connecting, and if the server is not the one you write to, communicate with the server-side developer

Socket connection-(void) socketconnecthost{self.socket = [[Asyncsocket alloc] initwithdelegate:self];    Nserror *error = nil; [Self.socket connectToHost:self.socketHost onPort:self.socketPort withtimeout:3 error:&error];}

Heartbeat

The heartbeat is realized by a timer.
Declaring a timer in the Singleton.h

@property (nonatomic, retain) Nstimer *connecttimer; Timer

Implement the connection success callback method in. m, and initialize the timer in this method to send the heartbeat when sending data to the server

#pragma mark-Connection succeeded Callback-(void) Onsocket: (Asyncsocket *) sock didconnecttohost: (NSString *) host port: (UInt16) port{NSLog (@    "Socket connection succeeded"); Every 30s like the server sends heartbeat packet Self.connecttimer = [Nstimer scheduledtimerwithtimeinterval:30 target:self selector: @selector ( Longconnecttosocket) Userinfo:nil repeats:yes];//The message sent to the server for a long connection in the Longconnecttosocket method [Self.connecttimer fire];}

2. Socket disconnected and re-connected

Disconnect Connection

There are several cases of loss of connectivity, the server is disconnected, the user active cut, but also may be like QQ other device login is dropped, regardless of that situation, we can receive the socket callback method returned to our message, if the user is logged out or the program exits the need for manual cut, We assign a value to the userdata of the socket before the cut to mark the user's exit so that we can determine what caused the drop when we receive the break information.

Declaring an enumeration type in an. h file

enum{socketofflinebyserver,//Server Drop line, the default is 0 socketofflinebyuser,//user active Cut};

Declaring a disconnect method

-(void) cutoffsocket; Disconnecting the socket connection

. m

Cut off socket-(void) cutoffsocket{self.socket.userData = socketofflinebyuser;//declaration is initiated by the user to cut [Self.connecttimer Invalida    TE]; [Self.socket disconnect];}

reconnects

Implementing Proxy methods

-(void) Onsocketdiddisconnect: (asyncsocket *) Sock{    nslog (@ "sorry the  connect is failure %ld ", Sock.userdata);    if  (sock.userData  == socketofflinebyserver)  {        //  server dropped, re-connected         [self socketConnectHost];    }     else if  (Sock.userdata == socketofflinebyuser)  {         //  if disconnected by the user, do not re-connect         return;     }} 

3. Socket send and receive data

Send Data
We add a method of not completing the heartbeat connection above

Heartbeat connection-(void) longconnecttosocket{//Send fixed-format data according to server requirements, assuming the directive @ "Longconnect", but generally not as simple as instructions nsstring *longconnect = @ "    Longconnect ";    NSData *datastream = [Longconnect datausingencoding:nsutf8stringencoding]; [Self.socket writedata:datastream withtimeout:1 tag:1];}

Socket send data is stored in the form of a stack, all data placed in a stack, access will appear sticky packet phenomenon, so many times the server in sending and receiving data is to send the content byte length, and then send the form of content, get the data is also first to get a length, Then according to this length in the stack to read this length of the byte stream, if this is the case, send the data only need to send a length before sending the content, the sending method is the same as the sending content, assuming a length of 8

NSData *datastream = [@8 datausingencoding:nsutf8stringencoding]; [Self.socket writedata:datastream withtimeout:1 tag:1];

Receive Data
In order to receive the message of the socket at all times, we read the data in the long connection method

[Self.socket readdatawithtimeout:30 tag:0];

If the data is obtained, the callback method is called

-(void) Onsocket: (Asyncsocket *) sock didreaddata: (NSData *) data withtag: (long) tag{//To parse and convert the resulting data value [Self.socket Readdatawithtimeout:30 tag:0];}

4. Simple use instructions

We in the user login the first interface to the socket initialization connection operation, after getting the data, will need to display the data in the singleton, the variable is monitored after the corresponding operation can be extended to more complex, no real data is not too convenient to explain, Let's explore it yourself, please leave a message below

     [singleton sharedinstance].sockethost = @ "192.186.100.21";//  Host setting     [singleton sharedinstance].socketport = 10045;// port settings     //  manually disconnect     [singleton sharedinstance before connecting]. socket.userdata = socketofflinebyuser;    [[singleton sharedinstance]  cutoffsocket];    //  be sure to disconnect and then crash if connecting to a socket that is in a connected state     [ singleton sharedinstance].socket.userdata = socketofflinebyserver;    [[ Singleton sharedinstance] socketconnecthost]; 

All the code here, just the integration of this article, run out as blank


iOS learning socket using a simple tutorial-asyncsocket

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.