建立网络通信连接至少要一对端口号(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广播