SocketUdp的实现代码

socketUdp的使用

在我们与硬件进行通讯的时候将使用到socket通讯协议,我在做socket时使用的是简单的收发数据,核心就在于一个IP地址和Port端口号,至于需不需要绑定端口号,我在做UDP时是没有绑定端口号,下面我把具体的代码放在上面供大家参考:

在操作之前首先先要到github上下载GCDAsyncUdpScoket一个第三方封装的socket方法[这是socket封装的地址]:https://github.com/search?utf8=%E2%9C%93&q=asyncsocket

//服务端的代码
#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


#pragma mark ===发送指令====
- (void)SendMessage:(UIButton *)Send
{ 
    NSString *host = @"192.168.12.12" //IP地址
    uint16_t port = 8080//port端口号;

    //初始化udpsocket
    udpSocket = [[GCDAsyncUdpSocket alloc]initWithDelegate:self delegateQueue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)];
    //开始发送
    //改函数只是启动一次发送 它本身不进行数据的发送, 而是让后台的线程慢慢的发送 也就是说这个函数调用完成后,数据并没有立刻发送,异步发送
/*
    unsigned char sendout[512]={0};
    unsigned int i= 0;
   for( ; i < _RemoveArray.count; i++)
    {
        NSNumber *b = _RemoveArray[i];
        sendout[i] = (unsigned char)b.intValue;
}

    int Intag = 0;
    for (int i = 0; i < _InArray.count; i++) {
        NSNumber *number = _InArray[i];
        Intag  = number.intValue;

    }

    kice_t kic = signal_map_cmd(Intag, sendout, i , [SignalValue ShareValue].Integer);*/
    //以上注释的是我做的data数据,使用C++写的命令做成IOS中NSData类型的数据
    //这里是你要发送的数据为data类型的数据;     
    NSData *data = [NSData dataWithBytes:(void *)&kic   length:kic.size];
    [udpSocket sendData:data toHost:host port:port withTimeout:60 tag:200]; //这里的withTimeout没有实际的意义,只是做一个标记用的tag也是一样,只是在下面的代理方法中标示一下是否是发送成功还是失败,返回的信息方便我们知道状态;

    //bind端口,可以写可以不写,建议不写在实际的操作中在某一个页面如果没有发送指令,本页面的其他发送数据指令后是接受不到数据的,不写就可以操作
    [udpSocket bindToPort:_port error:nil];
    [udpSocket receiveOnce:nil]; //表示只接受一次数据

   // [[SignalValue ShareValue].GetMessage removeAllObjects];//这个是自己本人写的,对数组的操作,不要写   
}

#pragma mark === udpSocket执行的代理方法=======
//发送成功
-(void)udpSocket:(GCDAsyncUdpSocket *)sock didSendDataWithTag:(long)tag
{
    if (tag == 200) {
        NSLog(@"标记为200的数据发送完成了");
    }
}
    //发送失败
- (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 *str = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
    /*注释部分是我自己在接受导数据后做的处理,接受到数据后怎么处理就看自己的了
    unsigned char *a= [data bytes];
    kice_t *kic = (kice_t *)a;
    unsigned char cmd = kic->data[0];
    if(cmd == 0x27)
    {
        sw_state_t *sw = (sw_state_t *)(&((kice_t *)a)->data[3]);
        _count = (unsigned int)(sw->input);
        [SignalValue ShareValue].Integer = _count;
        unsigned int buf[512] ={0};
        for(int i = 0; i < _count; i++)
        {
            buf[i] = (unsigned char)sw->group[_count + i];

            NSInteger value = (NSInteger)buf[i];

            NSNumber *number = [NSNumber numberWithInteger:value];
            [[SignalValue ShareValue].GetMessage addObject:number];

        }
    }
    */

    [sock receiveOnce:nil];
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [self SendBackToHost:ip port:port withMessage:str];
    });

}

-(void)SendBackToHost:(NSString *)ip port:(uint16_t)port withMessage:(NSString *)str
{
    NSString *Msg = @"我在发送消息";
    NSData *data = [Msg dataUsingEncoding:NSUTF8StringEncoding];
    [udpSocket sendData:data toHost:ip port:[SignalValue ShareValue].SignalPort withTimeout:60 tag:201];
}
以上是我在开发中写的客户端的代码,UDP是一种面向无连接实现起来很简单,注意线程问题在使用中,传值时可能会出现显示慢的问题,这时只要在主线程中操作返回的数据就好了代码如下
 dispatch_async(dispatch_get_main_queue(), ^{

 //在这里操作数据
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值