上篇文章貼出了頭文件的定義巩趁,現(xiàn)在來(lái)逐一實(shí)現(xiàn)和說(shuō)明。
uint8_t m_pBuffer[SOCKET_TCP_BUFFER] 和int m_nBufferLen
SOCKET_TCP_BUFFER 宏定義16384丛楚,m_pBuffer為總長(zhǎng)度為16384個(gè)字節(jié)的數(shù)組,為網(wǎng)絡(luò)緩沖區(qū),保存socket接收的字節(jié)流呀伙。
m_nBufferLen 準(zhǔn)確的說(shuō)是一個(gè)標(biāo)識(shí)位,記錄緩沖區(qū)的數(shù)據(jù)的長(zhǎng)度(這個(gè)變量在解析緩沖區(qū)數(shù)據(jù)時(shí)要用到)添坊。
id<SocketDelegate>?delegate ? 解析數(shù)據(jù)完成后進(jìn)行分發(fā)的接口(在第三篇中會(huì)詳細(xì)說(shuō)明)剿另。
AsyncSocket*m_pSocket ?保存第三方封裝socket的實(shí)例。
一贬蛙,初始化api,這個(gè)實(shí)現(xiàn)很簡(jiǎn)單雨女,對(duì)變量進(jìn)行初始化,初始化后我們就有了可以調(diào)用的socket(m_pSocket)
/**創(chuàng)建*/
+ (instancetype)CreateTcpIPStream:(id)delegate
{
return [[TCPIPStreamalloc] initTcpIPSteam:delegate];
}
/**初始化*/
- (instancetype)initTcpIPSteam:(id)delegate
{
if(self= [super init]) {
_m_pSocket= [[AsyncSocketalloc]initWithDelegate:self];
_delegate= delegate;
m_nBufferLen=0;
}
return self;
}
二阳准,建立連接
1氛堕,每次重新連接服務(wù)器時(shí)都要將緩沖區(qū)相關(guān)變量設(shè)置成初始值,將buffer設(shè)置成0野蝇;
2讼稚,連接服務(wù)器前一定要判斷該socket斷開(kāi)位喂,否則會(huì)報(bào)錯(cuò);
3乱灵,網(wǎng)路檢測(cè)塑崖,是檢查設(shè)備網(wǎng)絡(luò)情況;
4痛倚,調(diào)用- (BOOL)connectToHost:(NSString*)hostname onPort:(UInt16)port error:(NSError**)errPtr 與服務(wù)器建立連接
? ? 根據(jù)errPtr的錯(cuò)誤信息做處理规婆;
5,這個(gè)是避免鎖屏的時(shí)候socket斷開(kāi)(不處理會(huì)拋異常)
-(void)CreateConnectWithAddress:(NSString*)address port:(uint)port
{
//清零數(shù)據(jù)
m_nBufferLen=0;
memset(m_pBuffer,0,sizeof(uint8_t)*SOCKET_TCP_BUFFER); ?//1
//重置網(wǎng)絡(luò)
[self.m_pSocket disconnect]; ? ? ? ?//2
//網(wǎng)絡(luò)檢測(cè) ? ? ? ? ? ?//3
//連接網(wǎng)絡(luò)這里要處理是否鏈接成功
NSError*erro;
if(self.m_pSocket==nil) {
self.m_pSocket= [[AsyncSocketalloc]initWithDelegate:self];
}
BOOLisSuccess = [self.m_pSocket connectToHost:addresson Port:porterror:&erro]; ?//4
NSLog(@"%@",@(isSuccess));
NSAssert(isSuccess,@"連接失敗");
//設(shè)置鎖屏連接不斷 ?//5
CFReadStreamSetProperty([self.m_pSocketgetCFReadStream],kCFStreamNetworkServiceType,kCFStreamNetworkServiceTypeVoIP);
CFWriteStreamSetProperty([self.m_pSocketgetCFWriteStream],kCFStreamNetworkServiceType,kCFStreamNetworkServiceTypeVoIP);
}
三蝉稳,發(fā)送數(shù)據(jù)
為了安全抒蚜,可以在發(fā)送前進(jìn)行加密
-(bool)SendToServer:(uint8_t*)pData size:(uint)nDataSize
{
//這里處理加密
//發(fā)送數(shù)據(jù)
[self.m_pSocket writeData:[NSDatadataWithBytes:pData length:nDataSize]withTimeout:-1tag:0];
returnYES;
}
四,接收數(shù)據(jù)
接收數(shù)據(jù)接口的實(shí)現(xiàn)是根據(jù)客戶(hù)端與服務(wù)端自定義協(xié)議實(shí)現(xiàn)的耘戚,后面我回專(zhuān)門(mén)用一篇文章來(lái)講這部分的實(shí)現(xiàn)嗡髓。-(void) onSocket:(AsyncSocket*)sock didReadData:(NSData*)data withTag:(long)tag
五,?關(guān)閉
-(void)ClosedStream
{
[self.m_pSocket disconnect];
}
六收津,協(xié)議實(shí)現(xiàn)
與服務(wù)器連接成功后饿这,會(huì)回調(diào)這個(gè)函數(shù),在此函數(shù)調(diào)用讀取數(shù)據(jù)的api撞秋,當(dāng)有數(shù)據(jù)來(lái)時(shí)就會(huì)回調(diào)-(void) onSocket:(AsyncSocket*)sock didReadData:(NSData*)data withTag:(long)tag长捧。
/**建立連接后調(diào)用*/
- (void)onSocket:(AsyncSocket*)sock didConnectToHost:(NSString*)host port:(UInt16)port
{
[self.m_pSocket readDataWithTimeout:-1tag:0];
}
這個(gè)socket關(guān)閉(正常或異常)時(shí)會(huì)調(diào)用吻贿,這里是處理斷線(xiàn)重連的地方串结,在網(wǎng)絡(luò)開(kāi)發(fā)中,網(wǎng)絡(luò)的切換舅列,前后臺(tái)切換都會(huì)導(dǎo)致連接斷開(kāi)肌割,很好的處理這些情況會(huì)很大程度上提高用戶(hù)體驗(yàn),后面會(huì)具體講處理的思路帐要。
-(void) onSocket:(AsyncSocket*)socket willDisconnectWithError:(NSError*)err