本文介绍UDP协议的简单模拟场景demo.
首先介绍一下每个字眼:
HTTP/XMPP: 都是数据传输格式的协议.(这里不作累述)
TCP和UDP: 都是数据传输方式的协议.比如说我要给你钱, 我是以手把手的方式拿给你呢还是以快递的方式寄给你呢.
TCP(传输控制协议)
- 需要经过三次握手建立连接,形成一条传输通道,不断传输数据
- 传输数据的大小不受限制
- 是安全可靠的协议,但是速度稍慢
UDP(用户数据报协议)
- 不需要建立连接, 把数据封装成数据包扔给对面
- 每个数据包大小限制在64K内
- 因为不建立连接,所以对方可能收到也可能收不到数据(丢包),因此是不安全的协议, 但是速度比较快
什么时候用TCP,什么时候用UDP:##
对速度要求比较高的时候使用UDP, 对数据安全要求比较高的时候使用TCP.
比如说视频聊天, QQ聊天, 就用UDP; 数据传输,文件下载,就用TCP.
假如对于视频聊天来说,如果画质优先那就选用TCP, 如果流畅度优先那就选用UDP.
什么是Socket###
Socket应用于两个不同客户端之间的通信及数据传输.中文名字叫套接字.
编程源于生活. 打个活生生的例子来说, 汽车和加油机.我们如果想把加油机里面的油输到汽车上, 那么汽车这边需要有一个端口, 加油机这边也要有一个端口, 两边端口各加一个套接头套着(好比adaptor),然后中间连上管道来输油. 我认为Socket的角色就是这个套接头.
简单来说, 要想在两个客户端之间传数据, 那么两个客户端各自都要有一个Socket.
UDP协议下,一个客户端如何发数据给另一个客户端
如果客户端B想给客户端A发数据, 那么就需要知道两个东西, 一个是客户端A的IP地址, 一个是端口号.就好像你让我给一部车加油, 我需要知道是哪部车(IP)和这部车的哪个洞是加油洞(端口号).
下面我们用demo模拟两个客户端间通过UDP协议来发送数据.
思路如下:
客户端A:
1.用Xcode新建一个OC工程clientA作为客户端A, 它是接收方.
2.导入socket框架(把下载好的GCDAsyncUdpSocket.h和.m拖进工程即可)并import头文件
3.创建Socket对象
4.连接端口号
5.开启接收数据
6.遵守GCDAsyncUdpSocketDelegate协议,实现didReceiveData的代理方法,在里面拿到接收的数据.
客户端B:
1.用Xcode新建一个命令行工程clientB作为客户端B,它是发送方.
2.导入socket框架并import头文件(同上)
3.创建Socket对象
4.调用方法发送数据给客户端A(需要知道clientA的IP和端口号)
代码如下:
客户端A(clientA):
#import "ViewController.h"
#import "GCDAsyncUdpSocket.h"
@interface ViewController ()<GCDAsyncUdpSocketDelegate>
@property(nonatomic, strong) GCDAsyncUdpSocket *udpSocket;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//创建套接字socket
self.udpSocket = [[GCDAsyncUdpSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
//绑定端口号
NSError *error = nil;
[self.udpSocket bindToPort:5555 error:&error];
if (!error) {
NSLog(@"绑定端口成功");
}else {
NSLog(@"绑定端口失败");
}
//开启监听数据接收
[self.udpSocket beginReceiving:&error];
if (!error) {
NSLog(@"开启监听数据成功");
}else {
NSLog(@"开启监听数据失败");
}
}
//实现代理方法接收数据
-(void)udpSocket:(GCDAsyncUdpSocket *)sock didReceiveData:(NSData *)data fromAddress:(NSData *)address withFilterContext:(id)filterContext{
//把接收到的data转化为NSString
NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
//打印string
NSLog(@"接收到数据 %@", string);
}
@end
客户端B(clientB):
#import <Foundation/Foundation.h>
#import "GCDAsyncUdpSocket.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
//创建udpSocket对象
GCDAsyncUdpSocket *udpSocket = [[GCDAsyncUdpSocket alloc] initWithDelegate:nil delegateQueue:dispatch_get_main_queue()];
//创建要发送的data
NSString *string = @"Wales万岁,Wales永垂不朽!";
NSData *sentData = [string dataUsingEncoding:NSUTF8StringEncoding];
//发送data到clientA
//Host: 要发送到的IP地址
//port:要发送到的端口号
[udpSocket sendData:sentData toHost:@"127.0.0.1" port:5555 withTimeout:-1 tag:0];
//为了防止该程序一启动就挂掉
[[NSRunLoop mainRunLoop] run];
}
return 0;
}
两个工程(客户端)一起运行后, 客户端B给A发送了一个数据,在客户端A中打印的结果如下: