美文网首页
iOS Socket通信

iOS Socket通信

作者: CMD独白 | 来源:发表于2017-01-13 15:15 被阅读270次

    用socket从服务器上获取数据,有以下三种方法:
    第一种是使用封装好的第三方GCDAsyncSocket,下载地址是https://github.com/Yuzeyang/GCDAsyncSocketManager
    ,在网上可以搜到它的使用方法(有很多)。

    第二种是使用系统自带的方法,代码如下

    #import "SocketManager.h"
    
    @interface SocketManager ()<NSStreamDelegate>
    {
        NSInputStream *inputStream;
        NSOutputStream *outputStream;
    }
    @end
    @implementation SocketManager
    
    + (instancetype)sharedSocketManager {
        static SocketManager *socketManager = nil;
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            socketManager = [[SocketManager alloc] init];
        });
        return socketManager;
    }
    
    - (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode{
    
        NSLog(@"eventCode:%lu",(unsigned long)eventCode);
        switch (eventCode) {
            case NSStreamEventOpenCompleted:
                
                  NSLog(@"输入输出流打开完成");
                
                break;
              case NSStreamEventHasBytesAvailable:
    
                  NSLog(@"有字节可读");
                     [self readData];
                
                break;
               case NSStreamEventHasSpaceAvailable:
                
                  NSLog(@"可以发送字节");
                
                     break;
                 case NSStreamEventErrorOccurred:
                
                  NSLog(@" 连接出现错误");
                     break;
                case NSStreamEventEndEncountered:
                
                  NSLog(@"连接结束");
                
                     // 关闭输入输出流
                     [inputStream close];
                     [outputStream close];
        
                     // 从主运行循环移除
                     [inputStream removeFromRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
                     [outputStream removeFromRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
                     break;
                 default:
                     break;
         }
    
    }
    
    - (void)connect{
       
        NSString *host = IP地址;
        int port = 端口号;
        
        CFReadStreamRef readStream;
        CFWriteStreamRef writeStream;
        CFStreamCreatePairWithSocketToHost(NULL, (__bridge CFStringRef)host, port, &readStream, &writeStream);
        
         inputStream = (__bridge NSInputStream *)(readStream);
         outputStream = (__bridge NSOutputStream *)(writeStream);
        
        inputStream.delegate = self;
        outputStream.delegate = self;
        
        [inputStream scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
        [outputStream scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
        
        [inputStream open];
        [outputStream open];
        
    }
    
    - (void)login{
        写入的命令,此处省略
        [outputStream write:data.bytes maxLength:data.length];
    }
    
    
    - (void)readData{
            uint8_t buf[1024];
        
            NSInteger len = [inputStream read:buf maxLength:sizeof(buf)];
            NSData *data = [NSData dataWithBytes:buf length:len];
            
            NSString *recStr =  [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
            
            NSLog(@"%@",recStr);
    //    [self cleanUpStream:inputStream];
    }
    - (void)cleanUpStream:(NSStream *)stream
    {
        [stream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
        [stream close];
        
        stream = nil;
    }
    @end
    
    

    第三种方法是使用socket编程最底层的connect等方法,参考地址:http://blog.csdn.net/majiakun1/article/details/19357415
    ,代码如下:

    #import "SocketManager1.h"
    #include <stdio.h>
    #include <string.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <syslog.h>
    #include <errno.h>
    #include <stdlib.h>
    @implementation SocketManager1
    
    - (void)socketConnect:(NSString *)host Port:(int)port{
    
        const char *ip = IP地址;
        self.socketFD = socket(AF_INET, SOCK_STREAM, 0);
        NSData *dataLogin = [self login];
        NSInteger bytes = [dataLogin length];
        NSLog(@"socketFD:%d",self.socketFD);
        struct sockaddr_in nativeAdd;
        nativeAdd.sin_len = sizeof(struct sockaddr);
        nativeAdd.sin_family = AF_INET;
        nativeAdd.sin_port = htons(port);
        nativeAdd.sin_addr.s_addr = inet_addr(ip);
    
        self.status = connect(self.socketFD, (struct sockaddr *) &nativeAdd, sizeof(nativeAdd));
        if (-1 == self.status) {
            close(self.socketFD);
        }
        if (self.status <0) {
            NSLog(@"连接失败:%d",errno);
            
        }else{
        
            NSLog(@"连接成功:%d",self.status);
            self.status = write(self.socketFD, [dataLogin bytes], bytes);
            if (self.status <0) {
                NSLog(@"写入失败:%d",errno);
                
            }else{
                
                NSLog(@"登陆成功:%d",self.status);
                
                [self read];
            }
    
        }
      
    }
    
    - (void)read{
        [NSThread detachNewThreadSelector:@selector(thread:) toTarget:self withObject:@"thread1"];
    }
    
    - (void)thread:(NSString *)sender{
        
        NSThread *thread = [NSThread currentThread];
        NSLog(@"%@",thread);
      NSMutableData *data = [[NSMutableData alloc]init];
        BOOL waitingForData = YES;
        int i = 0;
        do {
            const char *buffer[10000];
            int length = sizeof(buffer);
            int result = read(self.socketFD, &buffer, length);
            NSLog(@"result:%d",result);
            if (result >0) {
                [data appendBytes:buffer length:result];
                NSLog(@"data:%@",data);
                
            }else{
                
                NSString *string = [[NSString alloc]initWithData:data encoding:NSASCIIStringEncoding];
                NSLog(@"string:%@",string);
                waitingForData = NO;
            }
            
            ++i;
            NSLog(@"i:%d",i);
           NSLog(@"waitingForData:%d",waitingForData);
        } while (waitingForData == YES);
    
    }
    - (NSData *)login{
      写入的命令,此处省略;
        return data;
    }
    
    
    

    注:服务器状态码
    1XX - 服务器的信息
    2XX - 表示请求成功
    200:请求成功
    201:成功创建连接
    202:接受请求
    3XX - 表示重定向
    302:表示重定向
    304:表示服务端资源没有变化,访问缓存
    问题 - 这次请求没有真正低访问服务器端
    305:使用代理
    4XX - 客户端错误
    400:错误的请求
    404:网页找不到
    403:拒绝访问
    405:请求类型不允许
    5XX - 服务端错误
    500:服务端错误
    502:路径错误
    504:请求超时
    505:http版本不支持

    相关文章

      网友评论

          本文标题:iOS Socket通信

          本文链接:https://www.haomeiwen.com/subject/rpdsbttx.html