? ? ? ? 在iOS开发中,UDP通讯现在大多也使用GCD,很少用Runloop。然后粗略的了解了下UDP通讯。
????????Socket 是应用层和传输层之间的一层抽象协议,可以用来进行进程间通信,一般有 UDP 和 TCP 两种通信方式,前者速度稍快,稳定性不好,无法丢包重传。后者速度稍慢一点,但稳定性很好,可以丢包重传。
本文首先介绍使用 Socket 进行 UDP 通信。
UDP 通信流程:
使用 Socket 进行 UDP 通信的流程如下:
(1).创建一个 socket 对象
(2).准备好目标主机 IP 和目标端口
(3).绑定本机的端口
(4).发送/接收数据
(5).关闭套接字
客户端代码实现:
// 初始化socket
-(void)initSocket {
self.title = @"服务器";
dispatch_queue_t dQueue = dispatch_queue_create("Server queue", NULL);
receiveSocket = [[GCDAsyncUdpSocket alloc] initWithDelegate:self
delegateQueue:dQueue];
NSError *error;
// 绑定一个端口(可选),如果不绑定端口, 那么就会随机产生一个随机的电脑唯一的端口
// 端口数字范围(1024,2^16-1)
[receiveSocket bindToPort:SERVERPORT error:&error];
if (error) {
NSLog(@"服务器绑定失败");
}
// 开始接收对方发来的消息
[receiveSocket beginReceiving:nil];
}
// 接收消息代理
-(void)udpSocket:(GCDAsyncUdpSocket *)sock didReceiveData:(NSData *)data fromAddress:(NSData *)address withFilterContext:(id)filterContext {
NSString *msg = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
/**
* 更新UI一定要到主线程去操作啊
*/
dispatch_sync(dispatch_get_main_queue(), ^{
self.textView.text = msg;
});
NSLog(@"客户端ip地址-->%@,port--->%u,内容-->%@",
[GCDAsyncUdpSocket hostFromAddress:address],
[GCDAsyncUdpSocket portFromAddress:address],
msg);
NSString *sendStr = @"我收到了";
NSData *sendData = [sendStr dataUsingEncoding:NSUTF8StringEncoding];
// 该函数只是启动一次发送 它本身不进行数据的发送, 而是让后台的线程慢慢的发送 也就是说这个函数调用完成后,数据并没有立刻发送,异步发送
[receiveSocket sendData:sendData toHost:[GCDAsyncUdpSocket hostFromAddress:address]
port:[GCDAsyncUdpSocket portFromAddress:address]
withTimeout:60
tag:500];
}
客户端代码实现:
-(void)viewDidLoad {
[super viewDidLoad];
self.title = @"客户端";
dispatch_queue_t qQueue = dispatch_queue_create("Client queue", NULL);
sendSocket = [[GCDAsyncUdpSocket alloc] initWithDelegate:self
delegateQueue:qQueue];
NSError *error;
[sendSocket bindToPort:CLIENTPORT error:&error];
if (error) {
NSLog(@"客户端绑定失败");
}
[sendSocket beginReceiving:nil];
}
// 发送消息
-(IBAction)sendMsgClick:(UIButton *)sender {
NSData *sendData = [msgTF.text dataUsingEncoding:NSUTF8StringEncoding];
[sendSocket sendData:sendData
toHost:ipTF.text
port:SERVERPORT
withTimeout:60
tag:200];
}
// 发送消息失败回调
-(void)udpSocket:(GCDAsyncUdpSocket *)sock didNotSendDataWithTag:(long)tag dueToError:(NSError *)error {
if (tag == 200) {
NSLog(@"client发送失败-->%@",error);
}
}
// 收到消息回调
-(void)udpSocket:(GCDAsyncUdpSocket *)sock didReceiveData:(NSData *)data fromAddress:(NSData *)address withFilterContext:(id)filterContext {
NSString *receiveStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"服务器ip地址--->%@,host---%u,内容--->%@",
[GCDAsyncUdpSocket hostFromAddress:address],
[GCDAsyncUdpSocket portFromAddress:address],
receiveStr);
dispatch_sync(dispatch_get_main_queue(), ^{
receiveLab.text = receiveStr;
});
}
// 关闭套接字,并销毁
-(void)dealloc {
[sendSocket close];
sendSocket = nil;
}
|