iOS UDP通讯

作者: dadahua | 来源:发表于2016-09-29 18:10 被阅读1257次

    前言:

    最近用GCDAsyncSocket写个小东西,UDP通讯现在大多也使用GCD,很少用Runloop。然后粗略的了解了下UDP通讯。
    它是比HTTP更加底层的通讯协议,特点是:传输快无连接,系统开销也少。
    更详细的基础知识:Socket理论知识
    GCDAsyncUdpSocket这个框架很强大,你只需绑定端口通过代理接受消息,和对象方法发送消息。

    Demo:

    TCP.gif

    简介

    1. 第一个界面作为服务器端,绑定端口号,监听端口号里面的消息。
    2. 第二个界面作为客户端发送消息,给服务器的端口号和局域网的IP地址(下图有获取本机IP地址方法),同时也绑定端口号,监听端口号里面消息。
    3. 消息发送后,服务器通过代理接受到消息,消息里面包括客户端的IP地址·端口·发送的内容。
    4. 服务器再在代理里面回复消息:“我收到了”,给客户端的IP地址·端口

    备注:获取本机IP地址方法。

    获取本机ip地址

    代码

    • 服务端
    // 初始化socket
    -(void)initSocket {
        
        self.title = @"服务器";
        dispatch_queue_t dQueue = dispatch_queue_create("Server queue", NULL);
        receiveSocket = [[GCDAsyncUdpSocket alloc] initWithDelegate:self
                                                      delegateQueue:dQueue];
        NSError *error;
    
        // 绑定一个端口(可选),如果不绑定端口, 那么就会随机产生一个随机的电脑唯一的端口
        // 端口数字范围(1024,2^16-1)
        [receiveSocket bindToPort:SERVERPORT error:&error];
        if (error) {
            NSLog(@"服务器绑定失败");
        }
        // 开始接收对方发来的消息
        [receiveSocket beginReceiving:nil];
    }
    
    // 接收消息代理
    -(void)udpSocket:(GCDAsyncUdpSocket *)sock didReceiveData:(NSData *)data fromAddress:(NSData *)address withFilterContext:(id)filterContext {
        
        NSString *msg = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
        /**
         *  更新UI一定要到主线程去操作啊
         */
        dispatch_sync(dispatch_get_main_queue(), ^{
            self.textView.text = msg;
        });
        NSLog(@"客户端ip地址-->%@,port--->%u,内容-->%@",
              [GCDAsyncUdpSocket hostFromAddress:address],
              [GCDAsyncUdpSocket portFromAddress:address],
              msg);
        
        NSString *sendStr = @"我收到了";
        NSData *sendData = [sendStr dataUsingEncoding:NSUTF8StringEncoding];
        // 该函数只是启动一次发送 它本身不进行数据的发送, 而是让后台的线程慢慢的发送 也就是说这个函数调用完成后,数据并没有立刻发送,异步发送
        [receiveSocket sendData:sendData toHost:[GCDAsyncUdpSocket hostFromAddress:address]
                           port:[GCDAsyncUdpSocket portFromAddress:address]
                    withTimeout:60
                            tag:500];
    }
    
    • 客户端
    -(void)viewDidLoad {
        [super viewDidLoad];
        self.title = @"客户端";
        dispatch_queue_t qQueue = dispatch_queue_create("Client queue", NULL);
        sendSocket = [[GCDAsyncUdpSocket alloc] initWithDelegate:self
                                                   delegateQueue:qQueue];
        NSError *error;
        [sendSocket bindToPort:CLIENTPORT error:&error];
        if (error) {
            NSLog(@"客户端绑定失败");
        }
        [sendSocket beginReceiving:nil];
    }
    
    // 发送消息
    -(IBAction)sendMsgClick:(UIButton *)sender {
        NSData *sendData = [msgTF.text dataUsingEncoding:NSUTF8StringEncoding];
        [sendSocket sendData:sendData
                      toHost:ipTF.text
                        port:SERVERPORT
                 withTimeout:60
                         tag:200];
    }
    
    // 发送消息失败回调
    -(void)udpSocket:(GCDAsyncUdpSocket *)sock didNotSendDataWithTag:(long)tag dueToError:(NSError *)error {
        
        if (tag == 200) {
            NSLog(@"client发送失败-->%@",error);
        }
    }
    
    // 收到消息回调
    -(void)udpSocket:(GCDAsyncUdpSocket *)sock didReceiveData:(NSData *)data fromAddress:(NSData *)address withFilterContext:(id)filterContext {
        
        NSString *receiveStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
        NSLog(@"服务器ip地址--->%@,host---%u,内容--->%@",
              [GCDAsyncUdpSocket hostFromAddress:address],
              [GCDAsyncUdpSocket portFromAddress:address],
              receiveStr);
        
        dispatch_sync(dispatch_get_main_queue(), ^{
            receiveLab.text = receiveStr;
        });
    }
    
    // 关闭套接字,并销毁
    -(void)dealloc {
        
        [sendSocket close];
        sendSocket = nil;
    }
    

    要点

    • 收到消息的回调方法里面,如果要更新UI的话,一定要切换到主线程里去实现操作。
    • 向对方发消息,方法参数的端口号要是 对方绑定的端口号。
      demo地址https://github.com/dadahua/Demo

    相关文章

      网友评论

        本文标题:iOS UDP通讯

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