美文网首页
UDP组播 socket

UDP组播 socket

作者: 三毛中队长 | 来源:发表于2017-03-02 09:15 被阅读0次

相关概念:

单播、多播(组播)和广播的区别  http://blog.csdn.net/wangerge/article/details/3931491

多播(组播)地址范围--224.0.0.0到239.255.255.255

广播地址: 255.255.255.255

应用场景:

家庭局域网设备组件一个局域网,各设备提供udp socket监听服务,手机客户端进入此局域网,并向局域网内发送组播或广播,对应设备响应组播并按需要与手机端建立tcp长连接通信

1.服务端:

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification

{

GCDAsyncUdpSocket *serverSocket = [[[GCDAsyncUdpSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()] autorelease];

NSError *bindError = nil;

//bindToPort绑定端口函数,只能使用在充当server 的socket上 client socket不能使用

//[serverSocket bindToPort:8099 interface:@"en1" error:&bindError]; //en1 随机分配的ip地址

[serverSocket bindToPort:8099 error:&bindError]; //该socket默认绑定到该机子网卡的ip地址

if (bindError) {

NSLog(@"bindError = %@",bindError);

}

NSError *receiveError = nil;

[serverSocket beginReceiving:&receiveError]; //开始接收数据,一定要否则后面无法接收数据 不接收数据时调用pauseReceiving

if (receiveError) {

NSLog(@"receiveError = %@",receiveError);

}

//[serverSocket joinMulticastGroup:@"224.0.1.23" error:nil];//该socket加入到组播224.0.1.23中,之后只要客户端socket向这个组播地址发消息,该socket都能收到 与客户端的发送地址必须一致才能接收

NSLog(@"%@",[serverSocket localHost]);

///////////////////////////服务开启时同时开启TCP服务监听,以便后面建立TCP连接

GCDAsyncSocket *socket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];

NSError *err = nil;

if(![socket acceptOnPort:8099 error:&err])//tcp socket的监听端口必须要与udp socket的端口一样 后面客户端才能正确与服务端建立tcp连接,因为客户端到时获取的端口是udp socket的端口

{

NSLog(@"err.description = %@",err.description);

}else

{

NSLog(@"%@",[NSString stringWithFormat:@"开始监听%d端口.",8099]);

}

/////////////////////////////

}

udpsocket的关键回调方法:接收到客户端socket发送的消息响应如下

- (void)udpSocket:(GCDAsyncUdpSocket *)sock didReceiveData:(NSData *)data

fromAddress:(NSData *)address

withFilterContext:(id)filterContext {

NSLog(@"sock = %@, ReceiveData = %@, fromAddress = %@",sock,[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding],[[NSString alloc] initWithData:address encoding:NSUTF8StringEncoding]);

NSString *responseMessage = @"已即受到";

NSString *host = nil;

uint16_t port = 0;

[GCDAsyncUdpSocket getHost:&host port:&port fromAddress:address];//可获取客户端socket的ip和端口,不过直接打印address是空的

NSLog(@"Adress = %@ %i",host,port);

[sock sendData:[responseMessage dataUsingEncoding:NSUTF8StringEncoding] toAddress:address withTimeout:-1 tag:10];//服务端回应客户端

}

Tcp socket关键回调方法

- (void)socket:(GCDAsyncSocket *)sender didAcceptNewSocket:(GCDAsyncSocket *)newSocket

{

NSLog(@"%@",[NSString stringWithFormat:@"建立与%@的连接",newSocket.connectedHost]);

s = newSocket;

s.delegate = self;

[s readDataWithTimeout:-1 tag:0];//必须调用

}

-(void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag

{

NSString *receive = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];

NSLog(@"%@",[NSString stringWithFormat:@"%@:%@",sock.connectedHost,receive]);

NSString *reply = [NSString stringWithFormat:@"收到:%@",receive];

[s writeData:[reply dataUsingEncoding:NSUTF8StringEncoding] withTimeout:-1 tag:0];

[s readDataWithTimeout:-1 tag:0];

}

2.客户端:

- (IBAction)broadCast:(id)sender {

GCDAsyncUdpSocket *udpSocket = [[[GCDAsyncUdpSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()] autorelease];

NSError *error = nil;

[udpSocket enableBroadcast:YES error:&error];//允许广播 必须 否则后面无法发送组播和广播

NSString *message = @"ttt";

//[udpSocket sendData:[message dataUsingEncoding:NSUTF8StringEncoding] withTimeout:-1 tag:10];//该函数只能用户已经连接的socket

[udpSocket sendData:[message dataUsingEncoding:NSUTF8StringEncoding] toHost:@"224.0.1.23"  port:8099 withTimeout:-1 tag:10];//客户端socket发送组播或是广播 根据host的ip地址来订

[udpSocket beginReceiving:nil];//必须要  开始准备接收数据

}

UDP 回调函数

- (void)udpSocket:(GCDAsyncUdpSocket *)sock didReceiveData:(NSData *)data

fromAddress:(NSData *)address

withFilterContext:(id)filterContext {

NSLog(@"ReceiveData = %@, fromAddress = %@",[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding],[[NSString alloc] initWithData:address encoding:NSUTF8StringEncoding]);

NSString *host = nil;

uint16_t port = 0;

[GCDAsyncUdpSocket getHost:&host port:&port fromAddress:address];//从此可以获取服务端回应的ip和端口 用于后面的tcp连接

NSLog(@"Adress = %@ %i",host,port);

//开启tcp连接

sockeTCP = [[GCDAsyncSocket alloc]initWithDelegate:self delegateQueue:dispatch_get_main_queue()];

//socket.delegate = self;

NSError *err = nil;

if(![sockeTCP connectToHost:host onPort:port error:&err])

{

}else

{

NSLog(@"tcp ok");

[sockeTCP writeData:[@"发送tcp消息" dataUsingEncoding:NSUTF8StringEncoding] withTimeout:-1 tag:0];

[sockeTCP readDataWithTimeout:-1 tag:0];

}

}

TCP 回调函数:

-(void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port

{

NSLog(@"%@",[NSString stringWithFormat:@"tcp连接到:%@",host]);

[sockeTCP readDataWithTimeout:-1 tag:0];

}

-(void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag

{

NSString *newMessage = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];

NSLog(@"tcp newMessage = %@",newMessage);

}

相关文章

  • UDP

    Linux C编程 socket——Udp组播(多播)[https://www.jianshu.com/write...

  • UDP组播 socket

    相关概念: 单播、多播(组播)和广播的区别 http://blog.csdn.net/wangerge/artic...

  • Socket

    先UDP组播 socket 再TCP建立长连接 同一个局域网下,各设备提供udp socket监听服务,手机客户端...

  • Unity UDP组播

    UDP的组播:服务器接受信息的端口必须和客户端接受信息的socket 端口一致。问:一个Udp Server加入某...

  • iOS UDP组播

    组播步骤: 建立socket socket和端口绑定 加入一个组播组 通过sendto / recvfrom进行数...

  • 网络通讯

    UDP UDP多播 多播(组播)的概念多播,也称为“组播”,将网络中同一业务类型主机进行了逻辑上的分组,进行数据收...

  • UDP广播,向飞秋发消息,模拟QQ-2018-04-02

    UDP广播 from socket import * udp_socket = socket(type=SOCK_...

  • UDP组播

    使用哪种协议实现 udp 不用保证数据可靠性,传输速度快;并且一般tcp是不用于多播场景的;那使用udp如何实现呢...

  • SOCKET,TCP/UDP,HTTP,FTP

    转。。。。。。。。 SOCKET,TCP/UDP,HTTP,FTP (一)TCP/UDP,SOCKET,HTTP,...

  • UDP收发消息-2018-04-02

    from socket import * udp_socket = socket(type=SOCK_DGRAM)...

网友评论

      本文标题:UDP组播 socket

      本文链接:https://www.haomeiwen.com/subject/mzlhgttx.html