iOS網(wǎng)絡(luò)編程之TCP/IP應(yīng)用篇(二)-框架的二次封裝

上篇文章貼出了頭文件的定義,現(xiàn)在來逐一實(shí)現(xiàn)和說明。

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)確的說是一個(gè)標(biāo)識(shí)位,記錄緩沖區(qū)的數(shù)據(jù)的長(zhǎng)度(這個(gè)變量在解析緩沖區(qū)數(shù)據(jù)時(shí)要用到)。

id<SocketDelegate>?delegate ? 解析數(shù)據(jù)完成后進(jìn)行分發(fā)的接口(在第三篇中會(huì)詳細(xì)說明)。

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斷開,否則會(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斷開(不處理會(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ù)客戶端與服務(wù)端自定義協(xié)議實(shí)現(xiàn)的,后面我回專門用一篇文章來講這部分的實(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ù)來時(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)用,這里是處理斷線重連的地方,在網(wǎng)絡(luò)開發(fā)中,網(wǎng)絡(luò)的切換,前后臺(tái)切換都會(huì)導(dǎo)致連接斷開,很好的處理這些情況會(huì)很大程度上提高用戶體驗(yàn),后面會(huì)具體講處理的思路。

-(void) onSocket:(AsyncSocket*)socket willDisconnectWithError:(NSError*)err

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容