因为公司是做智能硬件的,需要对硬件设备的状态进行实时的监听,硬件开发的同事对于Http协议并不是十分的了解,所以公司决定使用Socket来让移动设备与硬件设备进行通讯。
经过研究,使用CocoaAsyncSocket来实现IOS上的socket通讯。
下面就分享一下我使用CocoaAsyncSocket时的心得,也算做一个记录。
一.CocoaAsyncSocket介绍
CocoaAsyncSocket中主要包含两个类:
1.GCDAsyncSocket.
用GCD搭建的基于TCP/IP协议的socket网络库
GCDAsyncSocket is a TCP/IP socket networking library built atop Grand Central Dispatch. -- 引自CocoaAsyncSocket.
2.GCDAsyncUdpSocket.
用GCD搭建的基于UDP/IP协议的socket网络库.
GCDAsyncUdpSocket is a UDP/IP socket networking library built atop Grand Central Dispatch..-- 引自CocoaAsyncSocket.
二.下载CocoaAsyncSocket
1.使用pod进行下载
没有安装cocoapods的可以点这里学习进行安装.
已安装cocoapods的,在项目中的Podfile文件中加入:pod 'CocoaAsyncSocket' 后 install就好了.
2.直接下载
- 首先,需要到这里下载CocoaAsyncSocket.
下载后可以看到文件所在位置.
这里只要拷贝以下两个文件到项目中.
三.客户端的使用方法
MpdStatusSocket.h 文件
#import <Foundation/Foundation.h>
#import <GCDAsyncSocket.h>
#define SocketOfflineByServer @"SocketOfflineByServer"
#define SocketOfflineByUser @"SocketOfflineByUser"
@interface MpdStatusSocket : NSObject
+ (MpdStatusSocket *)sharedInstance;
// 断开socket连接
- (void)cutOffSocket;
// 设置Socket需要连接的ip和端口号Port
- (void)ConnectWithIp:(NSString *)ip onPort:(NSString *)Port;
// 发送命令
- (void)writeCommand:(NSString *)command withTag:(NSInteger)tag;
@end
MpdStatusSocket.m 文件
#import "MpdStatusSocket.h"
#define TimeOut 5 //超时时间
@interface MpdStatusSocket()<GCDAsyncSocketDelegate>
@property (nonatomic, strong) GCDAsyncSocket *socket;
@property (nonatomic, strong) NSString *HostStr;
@property (nonatomic, strong) NSMutableData *tempData;
@end
@implementation MpdStatusSocket
//使用单利模式
+(MpdStatusSocket *) sharedInstance
{
static MpdStatusSocket *sharedInstace = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstace = [[self alloc] init];
});
return sharedInstace;
}
- (void)ConnectWithIp:(NSString *)ip onPort:(NSString *)Port ConnectSuccess:(ConnectSuccess)success ConnectFailure:(ConnectFailure)failure{
if (self.socket == nil) {
self.socket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
}
if (!self.socket.isConnected) {
NSError *error = nil;
[self.socket connectToHost:ip onPort:Port withTimeout:3 error:&error];
}
}
// 连接成功的代理
-(void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port{
}
//socket断开,在这个函数中需要进行判断,判断是异常断开还是用户主动断开
-(void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err{
if ([self.socket.userData isEqual:SocketOfflineByUser]) {
// 用户退出后台主动切断socket
self.clientSocket.delegate = nil;
self.clientSocket = nil;
}else{
// 其他原因造成的Socket的中断,需要重新连接
NSError *error = nil;
[self.socket connectToHost:self.HostStr onPort:SocketPort withTimeout:TimeOut error:&error];
}
}
// 发送命令
- (void)writeCommand:(NSString *)command withTag:(NSInteger)tag{
NSData *dataStream = [commandStr dataUsingEncoding:NSUTF8StringEncoding];
[self.socket writeData:dataStream withTimeout:TimeOut tag:commandTag];
}
// 发送数据成功
-(void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag{
// 发送数据成功后,需要进行返回数据的读取
[self.socket readDataWithTimeout:TimeOut tag:tag];
}
// 收到服务器的数据,读取数据成功后通过SocketDataControl处理
-(void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag{
}
// 切断socket
-(void)cutOffSocket{
self.socket.userData = SocketOfflineByUser;// 声明是由用户主动切断
[self.socket disconnect];
}