文章来源:blog.csdn.net/cdy2143/art…
在项目中,一直都是用AsyncSocket的开源项目来做IOS的Socket的开发,现在遇到一个问题:当数据包比较频繁的发送到手机时,即使使用了readDataToData,还是会出现丢包的问题且读到的包中还会出现分割符。后面终于参考了其他的文章,看到GCDAsyncSocket,结果试了一把,readDataToData,能正常分割数据,即按行来分,且不丢包了。
使用GCDAsyncSocket的方法如下:
\
2、使用代码
[plain] view plain copy
- //建立连接
- -(NSError *)setupConnection {
- if (nil == socket)
- socket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
- NSError *err = nil;
- NSLog(@"IP: %@, port:%i",hostAddress,hostPort);
- if (![socket connectToHost:hostAddress onPort:hostPort error:&err]) {
- NSLog(@"Connection error : %@",err);
- } else {
- err = nil;
- }
- needConnect = YES;
- return err;
- }
- //判断是否是连接的状态
- -(BOOL)isConnected {
- return socket.isConnected;
- }
- //断开连接
- -(void)disConnect {
- needConnect = NO;
- [socket disconnect];
- }
- //取得连接
- -(void)getConnection {
- if (![socket isConnected]) {
- [self disConnect];
- // [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(setupConnection) userInfo:nil repeats:NO];
- // NSLog(@"scheduled start");
- [self setupConnection];
- }
- }
- -(void)sendCMD {
- [self getConnection];
- // NSString* cmd = [[NSString alloc] init];
- // cmd = [cmd stringByAppendingString:@"BBBB1,zzc,202cb962ac59075b964b07152d234b70,201304182033EEEE"];
- NSString* cmd = @"BBBB1,zzc,202cb962ac59075b964b07152d234b70,201304182033EEEE\n";
- NSData *data = [cmd dataUsingEncoding:NSUTF8StringEncoding];
- [socket writeData:data withTimeout:20 tag:1];
- }
- //socket连接成功后的回调代理
- -(void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port {
- NSLog(@"onSocket:%p didConnectToHost:%@ port:%hu", sock, host, port);
- [delegate networkConnected];
- [self listenData];
- }
- //socket连接断开后的回调代理
- -(void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err {
- NSLog(@"DisConnetion");
- [socket disconnect];
- [delegate networkDisconnect];
- // if (needConnect)
- // [self getConnection];
- }
- //读到数据后的回调代理
- -(void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag {
- NSLog(@"receive datas from method 1");
- // NSLog(@"Data length = %d",[data length]);
- [self listenData];
- [delegate readData:data];
- // [self splitData:data];
- // [self listenData];
- }
- -(void)socket:(GCDAsyncSocket *)sock didReadPartialDataOfLength:(NSUInteger)partialLength tag:(long)tag {
- NSLog(@"Reading data length of %d",partialLength);
- }
- //发起一个读取的请求,当收到数据时后面的didReadData才能被回调
- -(void)listenData {
- // NSString* sp = @"\n";
- // NSData* sp_data = [sp dataUsingEncoding:NSUTF8StringEncoding];
- [socket readDataToData:[GCDAsyncSocket LFData] withTimeout:-1 tag:1];
- // [socket readDataWithTimeout:-1 tag:1];
- }
3、附上从网络上取得到数据包后,自己用分割符来分割数据,如用换行符号分割数据包
[plain] view plain copy
- <p class="p1">NSMutableData<span style="font-family: Arial, Helvetica, sans-serif;">* restData;</span></p>//分割数据包
- -(void)splitData:(NSData*)orignal_data {
- NSUInteger l = [orignal_data length];
- NSLog(@"Data length1 = %d",l);
- NSString* sp = @"\n";
- NSData* sp_data = [sp dataUsingEncoding:NSUTF8StringEncoding];
- NSUInteger sp_length = [sp_data length];
- NSUInteger offset = 0;
- int line = 0;
- while (TRUE) {
- NSUInteger index = [self indexOfData:sp_data inData:orignal_data offset:offset];
- if (NSNotFound == index) {
- if (offset<l) {
- NSLog(@"Have data not read");
- NSRange range = {offset,l-offset};
- NSData* rest = [orignal_data subdataWithRange:range];
- if (restData == nil) {
- restData = [[NSMutableData alloc] init];
- }
- [restData appendData:rest];
- }
- return;
- }
- NSUInteger length = index + sp_length;
- NSRange range = {offset,length-offset};
- NSData* sub = [orignal_data subdataWithRange:range];
- if (restData != nil) {
- [restData appendData:sub];
- [delegate readData:restData];
- restData = nil;
- } else {
- NSLog(@"line %d",line++);
- [delegate readData:sub];
- }
- offset += length;
- }
- }
- //查找指定的数据包的位置
- - (NSUInteger)indexOfData:(NSData*)needle inData:(NSData*)haystack offset:(NSUInteger)offset
- {
- Byte* needleBytes = (Byte*)[needle bytes];
- Byte* haystackBytes = (Byte*)[haystack bytes];
- // walk the length of the buffer, looking for a byte that matches the start
- // of the pattern; we can skip (|needle|-1) bytes at the end, since we can't
- // have a match that's shorter than needle itself
- for (NSUInteger i=offset; i < [haystack length]-[needle length]+1; i++)
- {
- // walk needle's bytes while they still match the bytes of haystack
- // starting at i; if we walk off the end of needle, we found a match
- NSUInteger j=0;
- while (j < [needle length] && needleBytes[j] == haystackBytes[i+j])
- {
- j++;
- }
- if (j == [needle length])
- {
- return i;
- }
- }
- return NSNotFound;
- }
\