iOS UDP通訊

前言:

最近用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
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,836評論 18 139
  • iOS面試小貼士 ———————————————回答好下面的足夠了------------------------...
    不言不愛閱讀 2,002評論 0 7
  • 史上最全的iOS面試題及答案 iOS面試小貼士———————————————回答好下面的足夠了----------...
    Style_偉閱讀 2,377評論 0 35
  • 1、OC中創建線程的方法是什么?如果指定在主線程中執行代碼?如何延時執行代碼。【難度系數★★】 1)創建線程的方法...
    木旁_G閱讀 1,985評論 2 16
  • 相關概念: 單播、多播(組播)和廣播的區別 http://blog.csdn.net/wangerge/artic...
    三毛中隊長閱讀 4,192評論 0 1