zoukankan      html  css  js  c++  java
  • iOS -- 原生NSStream实现socket

    - (void)startSocket:(NSString *)address andPort:(int)port
    {
        CFReadStreamRef readRef;
        CFWriteStreamRef writeRef;
        
        CFStreamCreatePairWithSocketToHost(NULL, (__bridge CFStringRef)address, port, &readRef, &writeRef);
        
        _inputStream = (__bridge NSInputStream *)readRef;
        _outputStream = (__bridge NSOutputStream *)writeRef;
        
        // 设置流属性
        [_inputStream setProperty:NSStreamNetworkServiceTypeVoIP forKey:NSStreamNetworkServiceType];
        [_outputStream setProperty:NSStreamNetworkServiceTypeVoIP forKey:NSStreamNetworkServiceType];
        
        // 设置代理
        _inputStream.delegate = self;
        _outputStream.delegate = self;
        
        // 放到runloop中
        [_inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
        [_outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
        
        [_inputStream open];
        [_outputStream open];
    }
    
    // 断开 scoket 连接
    - (void)closeSocket {
        if(_inputStream){
            _inputStream.delegate = nil;
            [_inputStream close];
            [_inputStream removeFromRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
            _inputStream = nil;
        }
        if(_outputStream){
            _outputStream.delegate = nil;
            [_outputStream close];
            [_outputStream removeFromRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
            _outputStream = nil;
            [SVProgressHUD showSuccessWithStatus:@"断开连接成功"];
        }
        // 通知给界面
        [[NSNotificationCenter defaultCenter] postNotificationName:@"closeSocket" object:nil userInfo:nil];
    }
    
    // 代理的回调是在主线程
    #pragma mark - <NSStreamDelegate>代理方法
    - (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode
    {
        switch (eventCode) {
            case NSStreamEventNone:
                break;
            case NSStreamEventOpenCompleted:
                [SVProgressHUD showSuccessWithStatus:@"连接成功"];
                NSLog(@"成功建立连接, 形成输入输出管道");
                break;
            case NSStreamEventHasBytesAvailable:
                NSLog(@"有数据可读");
            {
                uint8_t buf[3072];
                NSInteger len = 0;
                NSInputStream *inputStream = (NSInputStream *)aStream;
                len = [inputStream read:buf maxLength:3072];
                
                if (len) {
                    _tempString = [NSMutableString string];
                    // 将16进制字符拼接起来
                    for (int i = 0; i < len; i++) {
                        NSMutableString *str = [NSMutableString stringWithFormat:@"%x", buf[i]];
                        if (str.length < 2) {
                            [str insertString:@"0" atIndex:0];
                        }
                        [_tempString appendString:str];
                    }
                    // 进行分包丶 粘包处理, 同时进行KVO监听可用的包
                    
                        [_stick_Subcontract_Package HandleResultOnReceiveData:_tempString];
                   
                }
                break;
            }
            case NSStreamEventHasSpaceAvailable:
                NSLog(@"可以发送数据");
                break;
            case NSStreamEventErrorOccurred:
                NSLog(@"有错误发生, 连接失败");
                [SVProgressHUD showErrorWithStatus:@"连接错误"];
            {
                [aStream close];
                break;
            }
            case NSStreamEventEndEncountered:
                [SVProgressHUD showErrorWithStatus:@"正常断开连接"];
                NSLog(@"正常断开连接");
                
            {
                [aStream close];
                [aStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
                aStream = nil;
                break;
            }
                
            default:
                break;
        }
    }

    有个问题, 就是这个没有实现异步接受消息.所以最好用asynSocket

  • 相关阅读:
    Jenkins+Docker+Git+Harbor流水线打包
    docker镜像批量打包
    二进制安装docker-18.06.3-ce
    kubeadm添加新master或node
    Host is not allowed to connect to this MySQL server
    RecyclerFullyManagerDemo【ScrollView里嵌套Recycleview的自适应高度功能】
    RecyclerSwipeAdapterDemo【使用AndroidSwipeLayout用于列表项侧滑功能】
    RecyclerViewItemTouchHelperDemo【使用ItemTouchHelper进行拖拽排序功能】
    Android APP应用启动页白屏(StartingWindow)优化
    KeyboardUtil【软键盘弹出后输入框上移一定的高度】
  • 原文地址:https://www.cnblogs.com/mafeng/p/6655847.html
Copyright © 2011-2022 走看看