iOS Socket UDP广播

建立网络通信连接至少要一对端口号(socket)。socket本质是编程接口(API),对TCP/IP的封装,TCP/IP也要提供可供程序员做网络开发所用的接口,这就是Socket编程接口;HTTP是轿车,提供了封装或者显示数据的具体形式;Socket是发动机,提供了网络通信的能力。

http://www.cnblogs.com/purpleraintear/p/6403053.html 这里有一篇关于UDP疑难杂症

创建 socket

    // 创建 socket
    // AF_INET IPv4; AF_INET6 IPv6
    // SOCK_STREAM TCP; SOCK_DGRAM UDP
    _socketFileDescriptor = socket(AF_INET, SOCK_DGRAM, 0);

发送广播

发送广播的时候,需要将socket设置为广播:

    // 设置socket的属性为广播
    int value = 1;
    int error = setsockopt(_socketFileDescriptor, SOL_SOCKET, SO_BROADCAST, (const void *)&value, sizeof(value));

发送广播数据:

dispatch_queue_t queue = dispatch_queue_create("net.qigge.socket", DISPATCH_QUEUE_CONCURRENT);
    dispatch_async(queue, ^{
        // 设置sendto 发送的地址
        struct sockaddr_in socketParameters;
        socketParameters.sin_family = AF_INET;
        socketParameters.sin_addr.s_addr = INADDR_BROADCAST;
        socketParameters.sin_port = htons([_port intValue]);
        sendto(_socketFileDescriptor, [data bytes], [data length], 0, (struct sockaddr *)&socketParameters22, sizeof(struct sockaddr));
        NSLog(@"sendto fail, errno=%d\n", errno); // errno 错误代码
    });

注意:当socket为阻塞模式时,sendto()和recvfrom()将会阻塞当前线程,应当将这个两个方法放入子线程中。

接收广播

接收广播之前,需要先绑定端口:

struct sockaddr_in socketParameters;
socketParameters.sin_family = AF_INET;
socketParameters.sin_addr.s_addr = htonl(INADDR_ANY);
socketParameters.sin_port = htons([_port intValue]);
int b = bind(_socketFileDescriptor, (struct sockaddr *)&socketParameters, sizeof(socketParameters));
if ( b < 0) {
        NSLog(@"服务端绑定失败");
        return;
    }
NSLog(@"服务端绑定成功!");

接收信息:

dispatch_queue_t queue = dispatch_queue_create("net.qigge.rec", DISPATCH_QUEUE_CONCURRENT);
    dispatch_async(queue, ^{
        while (1) {
            int                     err;
            struct sockaddr_storage addr;
            socklen_t               addrLen;
            uint8_t                 buffer[65536];
            ssize_t                 bytesRead;

            addrLen = sizeof(addr);
            
            bytesRead = recvfrom(_socketFileDescriptor, buffer, sizeof(buffer), 0, (struct sockaddr *) &addr, &addrLen);

            if (bytesRead < 0) {
                err = errno;
            } else if (bytesRead == 0) {
                err = EPIPE;
            } else {
                NSData *    dataObj;
                NSData *    addrObj;

                err = 0;

                dataObj = [NSData dataWithBytes:buffer length:(NSUInteger) bytesRead];
                addrObj = [NSData dataWithBytes:&addr  length:addrLen  ];
            }
        }
    });

服务端和客户端都适用于发送UDP广播和接收UDP广播

你可能感兴趣的:(iOS Socket UDP广播)