iOS网络编程TCP/IP应用篇(四)- 根据协议解析数据

iOS网络编程TCP/IP应用篇(四)- 根据协议解析数据


制定了协议,现在就根据协议编写代码,先贴出代码

/**接收数据*/

-(void) onSocket:(AsyncSocket*)sock didReadData:(NSData*)data withTag:(long)tag

{

//放回实际接收长度

NSUIntegernLen = [datalength];

////////////////////////////////////////////////////////////////////////////////////////////////

//长度效验

if(nLen <=0)

{

return;

}

NALog(@"接收长度:%@",@(nLen));

//m_nBufferLen+=nLen;

intnOff =0;

while(true)

{

unsignedlongnMaxCopy =MIN(nLen + m_nBufferLen,sizeof(m_pBuffer));//限制最大拷贝字节数

memcpy(m_pBuffer+m_nBufferLen, [databytes] + nOff, nMaxCopy);//

m_nBufferLen+= nMaxCopy;

if(m_nBufferLen

UInt8* pTemp =m_pBuffer;

while(m_nBufferLen>sizeof(TCP_Head))

{

//取出包头字节数据

charheadChar[sizeof(TCP_Head)];

memset(headChar,0,sizeof(headChar));

memcpy(headChar,m_pBuffer,sizeof(TCP_Head));

//取的数据长度

TCP_Head* head = (TCP_Head*)headChar;

intcurLen =ntohs(head->datalenth) ;

//长度效验,小于包头或者大于当前数据总长度,说明只接收了一半数据,跳出处理

if( curLenm_nBufferLen){

break;

}

//数据发送到代理做分类处理

if([self.delegaterespondsToSelector:@selector(SocketDelegateWithHeartRecvData:size:)])

[self.delegateSocketDelegateWithHeartRecvData:pTempsize:curLen];

else

NALog(@"委托没有实现协议");

//减去已处理长度

m_nBufferLen-=curLen;

//数据移动

memmove(m_pBuffer,m_pBuffer+curLen,m_nBufferLen);

}

//跳出判断

if(m_nBufferLen

NALog(@"处理完一次数据----------------------");

break;

}

}

//Read more from this socket.

[self.m_pSocketreadDataWithTimeout:-1tag:0];

}


回调中参数data就是socket接受的数据。

一,长度校验

如果data的长度为0,说明没有数据直接返回。

二,第一个while循环用于拷贝回到数据data到我们定义的m_pBuffer中去,这里要注意不能覆盖m_pBuffer中原来的数据,所以用m_nBufferLen来标记拷贝起始位置。拷贝完之后对相应的变量做处理,如果m_pBuffer中的数据大小小于TCP_HEAD说明不是一个完整的包,跳出循环等待下一次回调。

三,第二个while循环是处理m_pBuffer中有多个数据包的情况。

每次循环到要判断buffer中的数据是不是大于包头,大于包头才执行下面的逻辑。

1,取出包头2,取出包头里datalenth这个字段,这里要注意大小端的问题(根据服务器情况,ios是小端,不清楚可以去Google一下)3,对datalenth这个字段做校验,一个包体的长度不可能小于包头或大于整个缓冲区,这里根据实际情况处理,一般就是丢弃,验证完后就分发到代理去解析命令,这样就保证代理接收的数据包是完整的正确的一个包,处理完后要把m_nBufferLen处理一下,同时对buffer做处理

以上就是根据协议做的数据处理,协议是可以扩展的,所以这段代码也是根据协议写的。下篇会介绍代理的数据包处理及怎么发送数据包。


你可能感兴趣的:(根据)