在代理controller类中,实现socket的代理方法
#pragma mark - GCDAsyncSocketDelegate
// 已连接
- (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port
{
GessCoreLog(@"Connected: %@:%d", host, port);
_status = SocketConnectionStatusConnected;
if ([self.delegate respondsToSelector:@selector(socketConnectionDidConnectedToServer:)]) {
[self.delegate socketConnectionDidConnectedToServer:self];
}
//已经连接上之后,开始读取data,调用下面的readDataToLength:withTimeout:tag:方法,在此方法中会调用到socket的代理方法: socket:didReadData:tag:方法。
[_asyncSocket readDataToLength:self.packetHeaderLength withTimeout:self.receivingTimeoutInterval tag:TAG_FIXED_LENGTH_HEADER];
}
// 收到报文,按顺序循环接收报文头,报文体。
//此方法的第一次调用是已经连接上的方法调用的时候。会读取data,然后调用代理的此方法。此时tag就事上面的TAG_FIXED_LENGTH_HEADER,所以第一次执行读取header
- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data tag:(long)tag
{
switch (tag) {
case TAG_FIXED_LENGTH_HEADER: { // 1.已读取报文头,计算长度后继续读取报文体
NSString *lengthString = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease];
[_asyncSocket readDataToLength:[lengthString integerValue] withTimeout:self.receivingTimeoutInterval tag:TAG_RESPONSE_BODY];//继续读取数据,这次传的是TAG_RESPONSE_BODY,所以下次调用此方法的时候,执行TAG_RESPONSE_BODY部分。
}
break;
case TAG_RESPONSE_BODY: // 2.已读出报文体,转发报文体,然后继续读取报文头
if ([self.delegate respondsToSelector:@selector(socketConnection:didReceivedData:)]) {
[self.delegate socketConnection:self didReceivedData:data];
}
[_asyncSocket readDataToLength:self.packetHeaderLength withTimeout:self.receivingTimeoutInterval tag:TAG_FIXED_LENGTH_HEADER]; //继续读,下次调用此方法时,tag是TAG_FIXED_LENGTH_HEADER
break;
default:
break;
}
}