制定了协议,现在就根据协议编写代码,先贴出代码
/**接收数据*/
-(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做处理
以上就是根据协议做的数据处理,协议是可以扩展的,所以这段代码也是根据协议写的。下篇会介绍代理的数据包处理及怎么发送数据包。