美文网首页iOS即时通讯(IM)
iOS即时通讯-系统Socket

iOS即时通讯-系统Socket

作者: 肖旭晖 | 来源:发表于2018-08-23 16:56 被阅读68次

    首先要明白如何才能通信网络编程三要素:IP/端口号/协议

    • 1、连接到主机
    /*
    创建全局的输入输出流,并且配置代理
    */
    @interface SocketStream ()<NSStreamDelegate>
    @property (nonatomic, strong) NSInputStream *inputStream;//输入流
    @property (nonatomic, strong) NSOutputStream *outputStream;//输出流
    @end
    
    #pragma mark - 连接到主机
    -(void)connectToHost{
        
        //设置流的配置信息
        NSString *host = HOST;
        uint32_t port  = PORT;
        
        //定义C语言的输入输出流
        CFReadStreamRef readStream;
        CFWriteStreamRef writeStream;
        
        //与主机进行配对
        CFStreamCreatePairWithSocketToHost(NULL, (__bridge CFStringRef)host, port, &readStream, &writeStream);
        
        //C语音输入输出流转换成OC输入输出流
        self.inputStream = (__bridge NSInputStream *)(readStream);
        self.outputStream = (__bridge NSOutputStream *)(writeStream);
        
        //设置输入输出流代理
        self.inputStream.delegate = self;
        self.outputStream.delegate = self;
        
        //把输入输入流添加到主运行循环
        [self.inputStream scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
        [self.outputStream scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
        
        //打开输入输出流
        [self.inputStream open];
        [self.outputStream open];
    }
    
    
    • 2、进行输入输出流代理事件监听
    #pragma mark - NSStreamDelegate
    -(void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode{
        
        switch (eventCode) {
            case NSStreamEventOpenCompleted:
                NSLog(@"输入输出流打开完成");
                break;
                
            case NSStreamEventHasBytesAvailable:
                NSLog(@"有字节可读");
                //读取数据
                [self readData];
                break;
                
            case NSStreamEventHasSpaceAvailable:
                NSLog(@"可以发送字节");
                break;
                
            case NSStreamEventErrorOccurred:
                NSLog(@"连接出现错误");
                break;
                
            case NSStreamEventEndEncountered:
                NSLog(@"连接结束");
                [self disconnect];
        
                break;
                
            default:
                break;
        }
    }
    
    • 3、读取数据
    #pragma mark - 读取输入流服务器返回时调用代理方法中的数据
    -(void)readData{
    
        //建立一个缓冲区 可以放1024个字节
        uint8_t buf[1024];
        //返回实际装的字节数
        NSInteger len = [self.inputStream read:buf maxLength:sizeof(buf)];
        //把字节数组转化成字符串
        NSData *data =[NSData dataWithBytes:buf length:len];
        //从服务器接收到的数据
        NSString *reciveString =[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
        [self receiveMessage:reciveString];
    }
    
    #pragma mark - 接收数据
    -(void)receiveMessage:(NSString *)message{
        NSLog(@"接收消息啦:%@",message);
    }
    
    • 4、向服务器发送数据
      通过输出流NSOutputStream向服务器发送数据
    #pragma mark - 发送数据
    -(void)sendMessage:(NSString *)message{
        
        NSData *data = [message dataUsingEncoding:NSUTF8StringEncoding];
        [self.outputStream write:data.bytes maxLength:data.length];
    }
    

    例如:

    /*
    xmpp的一个消息包 其中:
    form:这个消息来自谁
    to:这个消息发给谁
    type:消息的类型(chat:单聊、room:群聊)
    body:消息体
    */
    <message from="zhangsan@www.baidu.com" 
             to="lisi@www.baidu.com"
             type="chat">
        <body>你好!</body>
        <active xmlns="http://jabber.org/protocol/chatstates"/>
    </message>
    
    

    这里的消息格式我们不限于xml、json和后台约定好

    • 5、登录到服务器
      连接到主机 socket通信管道已经建立,所谓的登录的过程就是向服务器验证账号密码的过程,通过第四步的输出流,向服务器发送一个验证格式的文本消息,这个过程中的数据可以进行加密等操作

    • 6、断开链接

    #pragma mark - 断开连接,并且把输入输出流从主运行循环中移除
    -(void)disconnect{
        
        [self.inputStream close]
        [self.outputStream close];
        [self.inputStream removeFromRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
        [self.outputStream removeFromRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
    }
    

    demo:https://github.com/xiaoxuhui1024/iOS-SystemSocket

    相关文章

      网友评论

        本文标题:iOS即时通讯-系统Socket

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