Use of Asyncsocket Library to handle socket communication in IOS applications _ios

Source: Internet
Author: User
Tags error handling socket error

With the socket can be implemented like QQ to send instant messaging functions. The client and the server need to establish a long connection, and in the case of a long connection, send the message. The client can send a heartbeat packet to detect long connections.

The use of sockets in iOS development, usually using a third-party library Asyncsocket, has to admit that the library is really powerful. Download Address Cocoaasyncsocket

Characteristics

The Asyncsocket class is TCP-enabled.
Asyncudpsocket is supported for UDP.
Asyncsocket is a TCP/IP socket network library that encapsulates Cfsocket and Cfsteam. It provides asynchronous operations, delegate-based full support for local cocoa classes. Mainly has the following characteristics:

    • Non-blocking read and write of queues, and optional timeout. You can call it read and write, it will be done after you are informed.
    • Automatic socket receive. If you call it to receive the connection, it will start a new instance for each connection and, of course, you can close the connection immediately.
    • Delegate (delegate) support. Errors, connections, receive, full reads, full writes, progress, and disconnection can all be invoked through delegate mode.
    • Based on the run loop, not the thread. Although it can be used in the main thread or in a worker thread, you do not need to do so. It asynchronously invokes the delegate method, using the Nsrunloop. The delegate method includes the parameters of the socket, allowing you to differentiate between multiple instances.
    • Self-contained in a class. You don't need to manipulate the flow or socket, this class helps you do it all.
    • Supports TCP streams based on IPV4 and IPV6.

Asyncudpsocket is UDP/IP socket network library, packaged from Cfsocket. It works much like a TCP version, but is used to handle UDP. It includes send and receive operations based on non-blocking queues, complete delegate support, Runloop based, self-contained classes, and support for IPV4 and IPV6.

Use Asyncsocket can do a layer of encapsulation, according to the requirements to provide several interfaces out. For example: Connect, disconnect, send messages, and so on. Also accept the message, received the message can be notified, agents, block, etc. outgoing.

The following is a brief introduction to the use of asyncsocket. Generally speaking, a user only need to establish a socket long connection, so you can use a single example class convenience.

Define a Single-column class: Lgsocketserve

LGSocketServe.h

Copy Code code as follows:

//
LGSocketServe.h
Asyncsocketdemo
//

#import <Foundation/Foundation.h>
#import "AsyncSocket.h"

@interface lgsocketserve:nsobject<asyncsocketdelegate>

+ (Lgsocketserve *) Sharedsocketserve;


@end


Lgsocketserve.m
Copy Code code as follows:

//
Lgsocketserve.m
Asyncsocketdemo
//

#import "LGSocketServe.h"

@implementation Lgsocketserve


static Lgsocketserve *socketserve = nil;

#pragma mark public static methods


+ (Lgsocketserve *) Sharedsocketserve {
@synchronized (self) {
if (Socketserve = = nil) {
Socketserve = [[[Self class] alloc] init];
}
}
return socketserve;
}


+ (ID) Allocwithzone: (Nszone *) zone
{
@synchronized (self)
{
if (Socketserve = = nil)
{
Socketserve = [Super Allocwithzone:zone];
return socketserve;
}
}
return nil;
}


@end


establish a socket long connection

LGSocketServe.h

Copy Code code as follows:

@property (nonatomic, strong) Asyncsocket *socket; Socket

Socket connection
-(void) startconnectsocket;
Lgsocketserve.m

Set yourself
#define HOST @ "192.168.0.1"
#define PORT 8080

Setting the connection timeout
#define TIME_OUT 20

-(void) Startconnectsocket
{
Self.socket = [[Asyncsocket alloc] initwithdelegate:self];
[Self.socket Setrunloopmodes:[nsarray Arraywithobject:nsrunloopcommonmodes]];
if (![ Self Socketopen:host Port:port])
{

}

}

-(Nsinteger) Socketopen: (nsstring*) addr port: (Nsinteger) port
{

if (![ Self.socket isconnected])
{
Nserror *error = nil;
[Self.socket connecttohost:addr onport:port withtimeout:time_out error:&error];
}

return 0;
}


Macros define host, PORT, Time_out, and implement Startconnectsocket methods. This time to set the Asyncsocket agent Asyncsocketdelegate. When a long connection succeeds, it is invoked:
Copy Code code as follows:

-(void) Onsocket: (Asyncsocket *) sock didconnecttohost: (NSString *) host port: (UInt16) port
{
This is a successful connection that was returned asynchronously.
NSLog (@ "Didconnecttohost");
}

Heartbeat

LGSocketServe.h

Copy Code code as follows:

@property (nonatomic, retain) Nstimer *hearttimer; Heartbeat Timer
Lgsocketserve.m

-(void) Onsocket: (Asyncsocket *) sock didconnecttohost: (NSString *) host port: (UInt16) port
{
This is a successful connection that was returned asynchronously.
NSLog (@ "Didconnecttohost");

Constantly send messages through the timer to detect long connections
Self.hearttimer = [Nstimer scheduledtimerwithtimeinterval:2 target:self selector: @selector (Checklongconnectbyserve) Userinfo:nil Repeats:yes];
[Self.hearttimer fire];
}

Heartbeat connection
-(void) checklongconnectbyserve{

Send a fixed message to the server to detect long connections
NSString *longconnect = @ "Connect is here";
NSData *data = [Longconnect datausingencoding:nsutf8stringencoding];
[Self.socket writedata:data withtimeout:1 tag:1];
}


In the successful callback method, the start timer sends a fixed message to the server every 2 seconds to detect the long connection. (This is based on the needs of the server)

Disconnect

1, user manually disconnect

LGSocketServe.h

Copy Code code as follows:

Disconnect the socket connection
-(void) cutoffsocket;
Lgsocketserve.m

-(void) Cutoffsocket
{
Self.socket.userData = Socketofflinebyuser;
[Self.socket disconnect];
}


Cutoffsocket is not trying to reconnect after the user disconnects.

2,wifi disconnected, socket disconnected

Lgsocketserve.m

Copy Code code as follows:

-(void) Onsocket: (Asyncsocket *) sock willdisconnectwitherror: (Nserror *) err
{

NSLog (@ "willdisconnectwitherror%ld err =%@", sock.userdata,[err description]);
if (Err.code = = 57) {
Self.socket.userData = Socketofflinebywificut;
}

}


After the WiFi is disconnected, the Onsocket:willdisconnectwitherror is recalled: method, Err.code = 57, this time setting Self.socket.userData = Socketofflinebywificut.

Re-connect

When the socket is disconnected, it is recalled:

Lgsocketserve.m

Copy Code code as follows:

-(void) Onsocketdiddisconnect: (Asyncsocket *) sock
{

NSLog (@ "7878 sorry the Connect is failure%ld", sock.userdata);

if (Sock.userdata = = Socketofflinebyserver) {
Server off line, heavy attached
[Self startconnectsocket];
}
else if (Sock.userdata = = Socketofflinebyuser) {

If disconnected by user, no connection is made
Return
}else if (sock.userdata = = socketofflinebywificut) {

WiFi disconnected, no heavy connection
Return
}

}


In the Onsocketdiddisconnect callback method, the Self.socket.userData is used to determine if reconnection is required.

Send a message

LGSocketServe.h

Copy Code code as follows:

Send a message
-(void) SendMessage: (ID) message;
Lgsocketserve.m

Set write timeout-1 means no timeout is used
#define Write_time_out-1

-(void) SendMessage: (ID) message
{
Send data like a server
NSData *cmddata = [message datausingencoding:nsutf8stringencoding];
[Self.socket writedata:cmddata withtimeout:write_time_out tag:1];
}

Callback after successful send message
-(void) Onsocket: (Asyncsocket *) sock Didwritedatawithtag: (long) tag
{

}


When a message is sent successfully, Onsocket:didwritedatawithtag is invoked: In this method, the message can be read.

Accept Message

Lgsocketserve.m

Copy Code code as follows:

Set read timeout-1 means no timeout is used
#define Read_time_out-1

#define Max_buffer 1024

Callback after successful send message
-(void) Onsocket: (Asyncsocket *) sock Didwritedatawithtag: (long) tag
{
Read messages
[Self.socket readdatawithtimeout:-1 buffer:nil bufferoffset:0 maxlength:max_buffer tag:0];
}

Callback after successful acceptance of message
-(void) Onsocket: (Asyncsocket *) sock didreaddata: (NSData *) data withtag: (long) tag
{
When the server side returns a large amount of message data, it may be returned multiple times. So when reading the message, set Max_buffer to say how much each time reads, when Data.length < Max_buffer we think it is possible to accept a complete message before parsing
if (Data.length < Max_buffer)
{
Receive result resolution ...
Nsdictionary *dic = [nsjsonserialization jsonobjectwithdata:data options:nsjsonreadingmutableleaves Error:nil];
NSLog (@ "%@", DIC);
The message can be sent out by notification, proxy, block, etc.

}


[Self.socket readdatawithtimeout:read_time_out buffer:nil bufferoffset:0 maxlength:max_buffer tag:0];


After receiving the message to resolve, and then through the notification, agent, block, etc. outgoing. In OnSocket:didReadData:withTag: The callback method needs to read the message continuously, because the data volume is larger, the server will be returned multiple times. So we need to define a Max_buffer macro that indicates how much to read at a time. When Data.length < Max_buffer we think it is possible to accept a complete message before parsing.

Error handling

Lgsocketserve.m

Copy Code code as follows:

-(void) Onsocket: (Asyncsocket *) sock willdisconnectwitherror: (Nserror *) err
{
NSData * Unreaddata = [sock unreaddata]; * * This gets the current buffer
if (Unreaddata.length > 0) {
[Self Onsocket:sock didreaddata:unreaddata withtag:0]; * * Return as much data as this could be collected
} else {

NSLog (@ "willdisconnectwitherror%ld err =%@", sock.userdata,[err description]);
if (Err.code = = 57) {
Self.socket.userData = Socketofflinebywificut;
}
}

}


Socket Error Callback Onsocket:willdisconnectwitherror: method, you can read the Unreaddata by reading the buffer.

Use

Import #import "LGSocketServe.h"

Copy Code code as follows:

Lgsocketserve *socketserve = [Lgsocketserve sharedsocketserve];
Disconnect before socket connection before socket connection causes flash back
[Socketserve Cutoffsocket];
SocketServe.socket.userData = Socketofflinebyserver;
[Socketserve Startconnectsocket];

Send a message @ "Hello World" just for example, depending on the message format of the service side
[Socketserve sendmessage:@ "Hello World"];

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.