1 , Asyncsocket Introduction
If you need to do instant messaging in your project like QQ, you must use socket communication.
IOS in Socket Programming the way :
BSD Socket:
BSD Socket is a common network interface in UNIX system, it not only supports a variety of network types, but also a communication mechanism between internal processes. The iOS system is essentially UNIX, so it can be used, but more complex.
Cfsocket:
Cfsocket is the way Apple provides us with a socket, but it's not very handy. Of course, if you want to use it, you can study it carefully.
Asyncsocket:
Third-party open source libraries, the preferred way, are often used in development projects.
Select Asyncsocket Reasons for:
The iphone's cfnetwork programming is more complex. Using the Asyncsocket open Source library for development is relatively simple and helps us encapsulate a lot of things.
Environment:
Download Asyncsocket:
Https://github.com/robbiehanson/CocoaAsyncSocket class Library, the Runloop folder AsyncSocket.h, ASYNCSOCKET.M, AsyncUdpSocket.h, Copy asyncudpsocket.m files to your own project
Add Cfnetwork.framework, and then use the socket's file header
#import <sys/socket.h>
#import <netinet/in.h>
#import <arpa/inet.h>
#import <unistd.h>
2 , Asyncsocket detailed
In actual development, the main task is to develop the client. So the following is the main explanation of the client's entire connection establishment process, and what functions are recalled at the time of the description.
Common methods:
1. Establish the connection
-(int)connectserver:(NSString *) hostip port: (int) Hostport
2, after the successful connection, the function will be callback
-(void) Onsocket: (Asyncsocket *) sock didconnecttohost:(NSString *) host port: (UInt16) port
3. Send data
-(void)writedata:(NSData *) data withtimeout: (nstimeinterval) timeout tag: (long) tag;
4. Acceptance of data
-(void) Onsocket: (Asyncsocket *) sock didreaddata:(NSData *) data withtag: (long) tag
5. Disconnect the connection
-(void) Onsocket: (Asyncsocket *) sock willdisconnectwitherror:(nserror *) err
-(void)onsocketdiddisconnect:(Asyncsocket *) sock
The main is the above several methods, just said in the real development, it is likely that we are in the sending and receiving data, we send and receive data is not only a string packaging into NSData can, we will probably send the structure and other types, This time we need to work with the server-side people to develop: define what kind of structure.
3 , the use of the method detailed
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 singleton or appdelegate for data sharing, preferred to use a singleton. 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 the socket is connected.
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.
Statement Socket variables:
@property (nonatomic, strong) Asyncsocket *socket; Socket @property (nonatomic, copy) NSString *sockethost; Socket host @property (nonatomic, assign) UInt16 Socketport; Socket's Prot
Connection ( long connection )
-(void) socketconnecthost;//socket connection
Both host and port are specified by the server when connecting.
// socket连接-(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.
@property (nonatomic, retain) Nstimer *connecttimer; Timer
A method that implements a successful connection callback, initializes the timer in this method, periodically sends a request to the server, keeps the connection
#pragma mark-Connection success Callback-(void)Onsocket: (Asyncsocket *) sockDidconnecttohost: (NSString *) hostPort: (uint16) port {nslog (@ " Socket connection succeeded "), // every 30s like 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 long connection in Longconnecttosocket method [
To disconnect the 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,//服务器掉线,默认为0SocketOfflineByUser, //用户主动cut};
Defining and implementing a Break method
-(void) cutoffsocket; Disconnecting the socket connection
// 切断socket-(void)cutOffSocket{self.socket.userData = SocketOfflineByUser;// 声明是由用户主动切断[self.connectTimer invalidate];[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;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;}}
Send data:
we add a method of not completing the heartbeat connection above
// 心跳连接-(void)longConnectToSocket{// 根据服务器要求发送固定格式的数据,假设为指令@"longConnect",但是一般不会是这么简单的指令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 {// 对得到的data值进行解析与转换即可[self.socket readDataWithTimeout:30 tag:0];}
"Remarks" about NSData objects
The NSData object is used regardless of whether the socket is sent or received.
The NSData is primarily a data space and length with a (ID) that is pointed to. NSString converted into NSData Object
nsdata* xmlData = [@ "TestData" datausingencoding:
Nsutf8stringencoding];
NSData converted into NSString Object
NSData * data;
NSString *result = [[NSString alloc] initwithdata:data encoding:
Nsutf8stringencoding];
Instant Messaging sockets for iOS development (Asyncsocket)