GCDAsyncUDPSocket源地址返回null [英] GCDAsyncUDPSocket source address returns null

查看:108
本文介绍了GCDAsyncUDPSocket源地址返回null的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Google代码问题镜像: https://groups.google.com/forum/#!topic/cocoaasyncsocket/grhjZSMLr3U

google code question mirror: https://groups.google.com/forum/#!topic/cocoaasyncsocket/grhjZSMLr3U

这是我的代码,正在读取响应:

here is my code that is reading the response:

- (void)init {
    udpSocket = [[GCDAsyncUdpSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];

    NSError *error = nil;
    if (![udpSocket bindToPort:UDP_PORT error:&error]) { //not connecting to host
        return;
    }
    if (![udpSocket beginReceiving:&error]) {
        return;
    }
}


- (void)udpSocket:(GCDAsyncUdpSocket *)sock
   didReceiveData:(NSData *)data
      fromAddress:(NSData *)address
withFilterContext:(id)filterContext
{
    NSString *msg = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    NSLog(@"got data from broadcast: %@",msg);

    NSString *src = [[NSString alloc] initWithData:address encoding:NSUTF8StringEncoding];
    NSLog(@"got src from broadcast: %@",src); 
}

这是发送udp bcast的代码:

here is the code sending the udp bcast:

- (void)send {
    [udpSocket enableBroadcast:YES error:nil];
    [udpSocket sendData:[self pack:@"134.71.146.49"] toHost:UDP_BCAST_ADDR port:UDP_PORT withTimeout:-1 tag:UDP_BROADCAST_SEND];
}

端口和bcast地址分别为55555和255.255.255.255.

port and bcast addr are 55555 and 255.255.255.255, respectively.

控制台输出:

got data from broadcast: 134.71.146.49
got src from broadcast: (null)

got data from broadcast: 134.71.146.49
got src from broadcast: (null)

十六进制:

 data:     <3133342e 37312e31 34362e34 39>
 address:  <1002d903 864793dd 00000000 00000000>

为什么此处的源地址为空?还是为什么它的格式不正确?

推荐答案

返回给您的地址字段实际上是一个扁平化为NSData对象的sockaddr_in结构.

The address field return to you is actually a sockaddr_in structure flattened into an NSData object.

这是结构:

struct sockaddr_in {
    __uint8_t   sin_len;
    sa_family_t sin_family;
    in_port_t   sin_port;
    struct  in_addr sin_addr;
    char        sin_zero[8];
};

从地址对象的显示中可以看到,第一个字段sin_len为0x10或16个字节.这就是sockaddr_in结构的长度.您可以使用它来判断地址对象是指向IPv4对象还是指向IPv6对象.一个IPv6对象将使用sockaddr_in6结构,并且长度更长.

You can see from your display of the address object that the first field, sin_len, is 0x10, or 16 bytes. That's the length of the sockaddr_in struct. You can use that to tell if the address object refers to an IPv4 object or an IPv6 object. An IPv6 object would use the sockaddr_in6 struct and have a longer length.

您可以将该NSData对象复制到sockaddr_in结构中,或者仅以正确的偏移量(4到7)拉出字节,以获得看起来更加熟悉的4字节源地址.

You could copy that NSData object into a sockaddr_in struct, or just pull out the bytes at the right offset (4 through 7) to get the 4-byte source address that looks more familiar.

这篇关于GCDAsyncUDPSocket源地址返回null的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆