IOS UDP通信

#import <UIKit/UIKit.h>

//包含了udp的socket(GCD/Blocks版本)
#import "GCDAsyncUdpSocket.h"

//這是一個接收 消息界面
@interface ViewController : UIViewController<GCDAsyncUdpSocketDelegate>{
    //udp對象
    GCDAsyncUdpSocket *udpServerSoket;
}
@end
#import "ViewController.h"
#import "SendViewController.h"

@interface ViewController ()

@end


@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.navigationItem.title = @"接收消息";
    [self showNavItem];
    [self createUdpSocket];
    
}
-(void)showNavItem{
    UIBarButtonItem *sendMyself = [[UIBarButtonItem alloc] initWithTitle:@"發送本身" style:UIBarButtonItemStylePlain target:self action:@selector(sendMyself)];
    self.navigationItem.rightBarButtonItem = sendMyself;
}

-(void)sendMyself{
    SendViewController *svc = [[SendViewController alloc] init];
    [self.navigationController pushViewController:svc animated:YES];
}

-(void) createUdpSocket{
    //建立一個後臺隊列 等待接收數據
    dispatch_queue_t dQueue = dispatch_queue_create("My socket queue", NULL); //第一個參數是該隊列的名字
    //1.實例化一個udp socket套接字對象
    // udpServerSocket須要用來接收數據
    udpServerSoket = [[GCDAsyncUdpSocket alloc]initWithDelegate:self delegateQueue:dQueue socketQueue:nil];
    
    //2.服務器端來監聽端口12345(等待端口12345的數據)
    [udpServerSoket bindToPort:12345 error:nil];
    
    //3.接收一次消息(啓動一個等待接收,且只接收一次)
    [udpServerSoket receiveOnce:nil];
}

#pragma mark -GCDAsyncUdpSocketDelegate
-(void)udpSocket:(GCDAsyncUdpSocket *)sock didReceiveData:(NSData *)data fromAddress:(NSData *)address withFilterContext:(id)filterContex
{
    //取得發送發的ip和端口
    NSString *ip = [GCDAsyncUdpSocket hostFromAddress:address];
    uint16_t port = [GCDAsyncUdpSocket portFromAddress:address];
    
    //data就是接收的數據
    NSString *s = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    
    NSLog(@"[%@:%u]%@",ip, port,s);
    
    [self sendBackToHost: ip port:port withMessage:s];
    //再次啓動一個等待
    [udpServerSoket receiveOnce:nil];
}
-(void)sendBackToHost:(NSString *)ip port:(uint16_t)port withMessage:(NSString *)s{
    NSString *msg = @"我已接收到消息";
    NSData *data = [msg dataUsingEncoding:NSUTF8StringEncoding];
    
    [udpServerSoket sendData:data toHost:ip port:port withTimeout:60 tag:200];
}


@end
#import <UIKit/UIKit.h>
#import "GCDAsyncUdpSocket.h"

@interface SendViewController : UIViewController<GCDAsyncUdpSocketDelegate>{
    //這個socket用來作發送使用 固然也能夠接收
    GCDAsyncUdpSocket *sendUdpSocket;
}
@end
#import "SendViewController.h"

@implementation SendViewController

-(void)viewDidLoad{
    [super viewDidLoad];
    self.navigationItem.title = @"發送";
    self.view.backgroundColor = [UIColor whiteColor];
    [self showNavItem];
    [self createClientUdpSocket];
}

- (void) showNavItem {
    UIBarButtonItem *sendMsg = [[UIBarButtonItem alloc] initWithTitle:@"發送消息" style:UIBarButtonItemStylePlain target:self action:@selector(sendMsg)];
    self.navigationItem.rightBarButtonItem = sendMsg;
}

-(void)createClientUdpSocket{
    dispatch_queue_t dQueue = dispatch_queue_create("client udp socket", NULL);
    
    //1.建立一個 udp socket用來和服務器端進行通信
    sendUdpSocket = [[GCDAsyncUdpSocket alloc] initWithDelegate:self delegateQueue:dQueue socketQueue:nil];
    
    //2.banding一個端口(可選),若是不綁定端口, 那麼就會隨機產生一個隨機的電腦惟一的端口
        //端口數字範圍(1024,2^16-1)
    [sendUdpSocket bindToPort:8085 error:nil];
    
    //3.等待接收對方的消息
    [sendUdpSocket receiveOnce:nil];
}

- (void) sendMsg {
    NSString *s = @"hello IOS";
    NSData *data = [s dataUsingEncoding:NSUTF8StringEncoding];
    NSString *host = @"10.0.161.87";
    uint16_t port = 12345;
    
    //開始發送
    //改函數只是啓動一次發送 它自己不進行數據的發送, 而是讓後臺的線程慢慢的發送 也就是說這個函數調用完成後,數據並無馬上發送,異步發送
    [sendUdpSocket sendData:data toHost:host port:port withTimeout:60 tag:100];
}

#pragma mark -GCDAsyncUdpSocketDelegate
-(void)udpSocket:(GCDAsyncUdpSocket *)sock didSendDataWithTag:(long)tag{
    if (tag == 100) {
        //NSLog(@"表示標記爲100的數據發送完成了");
    }
}
-(void)udpSocket:(GCDAsyncUdpSocket *)sock didNotSendDataWithTag:(long)tag dueToError:(NSError *)error{
    NSLog(@"標記爲tag %ld的發送失敗 失敗緣由 %@",tag, error);
}

-(void)udpSocket:(GCDAsyncUdpSocket *)sock didReceiveData:(NSData *)data fromAddress:(NSData *)address withFilterContext:(id)filterContext{
    NSString *ip = [GCDAsyncUdpSocket hostFromAddress:address];
    uint16_t port = [GCDAsyncUdpSocket portFromAddress:address];
    NSString *s = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    // 繼續來等待接收下一次消息
    NSLog(@"收到服務端的響應 [%@:%d] %@", ip, port, s);
    [sock receiveOnce:nil];
    
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            [self sendBackToHost:ip port:port withMessage:s];
    });
}

-(void)sendBackToHost:(NSString *)ip port:(uint16_t)port withMessage:(NSString *)s{
    
    
    NSString *msg = @"我再發送消息";
    NSData *data = [msg dataUsingEncoding:NSUTF8StringEncoding];
    
    [sendUdpSocket sendData:data toHost:ip port:port withTimeout:60 tag:200];
}

-(void)dealloc{
    NSLog(@"%s",__func__ );
    [sendUdpSocket close];
    sendUdpSocket = nil;
}

@end
相關文章
相關標籤/搜索