美文网首页iOS之开发配置
iOS之UDP广播作为服务端

iOS之UDP广播作为服务端

作者: shushuzhen | 来源:发表于2016-11-10 10:41 被阅读586次

    这篇就当做是为了备忘

    #import <Foundation/Foundation.h>
    #import "GCDAsyncUdpSocket.h"
    
    @protocol UDPServerSocketDelegate <NSObject>
    
    - (void)serverSocketDidReceiveMessage:(NSString *)message;
    
    @end
    
    @interface UDPServerSocket : NSObject <GCDAsyncUdpSocketDelegate>
    
    @property (nonatomic, weak)id <UDPServerSocketDelegate>delegate;
    
    @property (nonatomic, strong)GCDAsyncUdpSocket * udpSocket;
    
    @property (nonatomic, copy)NSString * clientIP;
    @property (nonatomic, assign)uint16_t clientPort;
    @property (nonatomic, assign)BOOL isSending;
    @property (nonatomic, strong)NSMutableArray * messageQueue;
    @property (nonatomic, copy)NSString * currentSendingMessage;
    @property (nonatomic,assign)NSInteger times;
    @property (nonatomic,assign)NSInteger resendTimes;
    
    - (void)startListenClientSocketMessage;
    
    - (void)sendMessage:(NSString *)message;
    
    @end
    

    服务端需要做的就是监听与客户端定好的端口就好,持续监听:

    #import "UDPServerSocket.h"
    
    @implementation UDPServerSocket
    
    - (void)startListenClientSocketMessage{
        dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
        GCDAsyncUdpSocket * udpSocket = [[GCDAsyncUdpSocket alloc]initWithDelegate:self delegateQueue:queue];
        self.udpSocket = udpSocket;
        self.isSending = NO;
        // 关联端口,监听端口
        NSError * error;
        [udpSocket bindToPort:5279 error:&error];
        
        
        // 接受一次消息(启动一个等待接受,且只接收一次)
        [udpSocket receiveOnce:nil];
    }
    
    - (void)udpSocket:(GCDAsyncUdpSocket *)sock didConnectToAddress:(NSData *)address{
        NSString * ip = [GCDAsyncUdpSocket hostFromAddress:address];
        uint16_t port = [GCDAsyncUdpSocket portFromAddress:address];
        
        self.clientIP = ip;
        self.clientPort = port;
        
        NSLog(@"sock: %@  didConnectToAddress:ip:%@  port:%d",sock,ip,port);
    }
    
    - (void)udpSocket:(GCDAsyncUdpSocket *)sock didReceiveData:(NSData *)data fromAddress:(NSData *)address withFilterContext:(id)filterContext{
        NSString * ip = [GCDAsyncUdpSocket hostFromAddress:address];
        uint16_t port = [GCDAsyncUdpSocket portFromAddress:address];
        
        self.clientIP = ip;
        self.clientPort = port;
        
        NSString * messgae = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
        
        NSLog(@"sock: %@  接收到消息:ip:%@  port:%d  message:%@",sock,ip,port,messgae);
        if ([self.delegate respondsToSelector:@selector(serverSocketDidReceiveMessage:)]) {
            [self.delegate serverSocketDidReceiveMessage:messgae];
        }
        [self sendBackToHost:ip port:port message:@"***************************************************"];
        
        self.times ++;
    //    NSLog(@"times:%ld",self.times);
        
        
        // 再次启动接收等待
        [self.udpSocket receiveOnce:nil];
    }
    
    - (void)sendMessage:(NSString *)message{
        [self.messageQueue addObject:message];
        if (!self.isSending) {
            [self sendBackToHost:self.clientIP port:self.clientPort message:message];
        }
    }
    
    - (void)udpSocket:(GCDAsyncUdpSocket *)sock didNotSendDataWithTag:(long)tag dueToError:(NSError *)error{
        NSLog(@"sock: %@  服务端发送失败 %@",sock,[error description]);
        self.resendTimes ++;
        if (self.resendTimes == 4) {
            [self.messageQueue removeObject:self.currentSendingMessage];
            self.currentSendingMessage = nil;
            self.isSending = NO;
        }else{
            [self sendBackToHost:self.clientIP port:self.clientPort message:self.currentSendingMessage];
        }
    }
    
    - (void)udpSocket:(GCDAsyncUdpSocket *)sock didSendDataWithTag:(long)tag{
        NSLog(@"sock: %@  服务端发送成功!   message:%@",sock,self.currentSendingMessage);
        [self.messageQueue removeObject:self.currentSendingMessage];
        self.isSending = NO;
        self.currentSendingMessage = nil;
    }
    
    - (void)udpSocketDidClose:(GCDAsyncUdpSocket *)sock withError:(NSError *)error{
        NSLog(@"sock: %@  断开连接  %@",sock,[error description]);
    }
    
    - (void)sendBackToHost:(NSString *)ip port:(uint16_t)port message:(NSString *)message{
        self.currentSendingMessage = message;
        self.isSending = YES;
        NSData * data = [message dataUsingEncoding:NSUTF8StringEncoding];
        [self.udpSocket sendData:data toHost:ip port:port withTimeout:-1 tag:0];
    }
    
    - (void)setIsSending:(BOOL)isSending{
        _isSending = isSending;
        if (!isSending && self.messageQueue.count) {
            [self sendBackToHost:self.clientIP port:self.clientPort message:[self.messageQueue firstObject]];
        }
    }
    
    - (NSMutableArray *)messageQueue{
        if (!_messageQueue) {
            _messageQueue = [[NSMutableArray alloc]init];
        }return _messageQueue;
    }
    

    相关文章

      网友评论

      • 呲嗯滋吴:能不能给个Demo,谢谢
        shushuzhen:@呲嗯滋吴 您好 这个demo的话其实就是这里面的h和m文件 你可以在网上把那个GCDAsyncUdpSocket拉下来导入就可以了的 服务端是要配合客户端一起使用才能收发消息的
        呲嗯滋吴:@shushuzhen chenzhu@95051.com
        shushuzhen:可以 留一个邮箱

      本文标题:iOS之UDP广播作为服务端

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