因?yàn)楣臼亲鲋悄苡布模枰獙?duì)硬件設(shè)備的狀態(tài)進(jìn)行實(shí)時(shí)的監(jiān)聽匠题,硬件開發(fā)的同事對(duì)于Http協(xié)議并不是十分的了解,所以公司決定使用Socket來讓移動(dòng)設(shè)備與硬件設(shè)備進(jìn)行通訊。
經(jīng)過研究缩功,使用CocoaAsyncSocket來實(shí)現(xiàn)IOS上的socket通訊。
下面就分享一下我使用CocoaAsyncSocket時(shí)的心得都办,也算做一個(gè)記錄嫡锌。
一.CocoaAsyncSocket介紹
CocoaAsyncSocket中主要包含兩個(gè)類:
1.GCDAsyncSocket.
用GCD搭建的基于TCP/IP協(xié)議的socket網(wǎng)絡(luò)庫
GCDAsyncSocket is a TCP/IP socket networking library built atop Grand Central Dispatch. -- 引自CocoaAsyncSocket.
2.GCDAsyncUdpSocket.
用GCD搭建的基于UDP/IP協(xié)議的socket網(wǎng)絡(luò)庫.
GCDAsyncUdpSocket is a UDP/IP socket networking library built atop Grand Central Dispatch..-- 引自CocoaAsyncSocket.
二.下載CocoaAsyncSocket
1.使用pod進(jìn)行下載
沒有安裝cocoapods的可以點(diǎn)這里學(xué)習(xí)進(jìn)行安裝.
已安裝cocoapods的,在項(xiàng)目中的Podfile文件中加入:pod 'CocoaAsyncSocket' 后 install就好了.
2.直接下載
- 首先,需要到這里下載CocoaAsyncSocket.
下載后可以看到文件所在位置.
這里只要拷貝以下兩個(gè)文件到項(xiàng)目中.
三.客戶端的使用方法
MpdStatusSocket.h 文件
#import <Foundation/Foundation.h>
#import <GCDAsyncSocket.h>
#define SocketOfflineByServer @"SocketOfflineByServer"
#define SocketOfflineByUser @"SocketOfflineByUser"
@interface MpdStatusSocket : NSObject
+ (MpdStatusSocket *)sharedInstance;
// 斷開socket連接
- (void)cutOffSocket;
// 設(shè)置Socket需要連接的ip和端口號(hào)Port
- (void)ConnectWithIp:(NSString *)ip onPort:(NSString *)Port;
// 發(fā)送命令
- (void)writeCommand:(NSString *)command withTag:(NSInteger)tag;
@end
MpdStatusSocket.m 文件
#import "MpdStatusSocket.h"
#define TimeOut 5 //超時(shí)時(shí)間
@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斷開,在這個(gè)函數(shù)中需要進(jìn)行判斷琳钉,判斷是異常斷開還是用戶主動(dòng)斷開
-(void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err{
if ([self.socket.userData isEqual:SocketOfflineByUser]) {
// 用戶退出后臺(tái)主動(dòng)切斷socket
self.clientSocket.delegate = nil;
self.clientSocket = nil;
}else{
// 其他原因造成的Socket的中斷势木,需要重新連接
NSError *error = nil;
[self.socket connectToHost:self.HostStr onPort:SocketPort withTimeout:TimeOut error:&error];
}
}
// 發(fā)送命令
- (void)writeCommand:(NSString *)command withTag:(NSInteger)tag{
NSData *dataStream = [commandStr dataUsingEncoding:NSUTF8StringEncoding];
[self.socket writeData:dataStream withTimeout:TimeOut tag:commandTag];
}
// 發(fā)送數(shù)據(jù)成功
-(void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag{
// 發(fā)送數(shù)據(jù)成功后,需要進(jìn)行返回?cái)?shù)據(jù)的讀取
[self.socket readDataWithTimeout:TimeOut tag:tag];
}
// 收到服務(wù)器的數(shù)據(jù)歌懒,讀取數(shù)據(jù)成功后通過SocketDataControl處理
-(void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag{
}
// 切斷socket
-(void)cutOffSocket{
self.socket.userData = SocketOfflineByUser;// 聲明是由用戶主動(dòng)切斷
[self.socket disconnect];
}