GCDAsyncUdpSocket 设置TTL

IP:TTL解释

虽然TTL从字面上翻译,是可以存活的时间,但实际上TTLIP数据包在计算机网络中可以转发的最大跳数。TTL字段由IP数据包的发送者设置,在IP数据包从源到目的的整个转发路径上,每经过一个路由器,路由器都会修改这个TTL字段值,具体的做法是把该TTL的值减1,然后再将IP包转发出去。如果在IP包到达目的IP之前,TTL减少为0,路由器将会丢弃收到的TTL=0IP包并向IP包的发送者发送 ICMP time exceeded消息。

TTL的主要作用是避免IP包在网络中的无限循环和收发,节省了网络资源,并能使IP包的发送者能收到告警消息。

TTL 是由发送主机设置的,以防止数据包不断在IP互联网络上永不终止地循环。转发IP数据包时,要求路由器至少将 TTL 减小 1


GCDAsyncUdpSocket 组播 设置TTL

GCDAsyncUdpSocket 发送组播 

socekt默认的ttl值为1

GCDAsyncUdpSocket中没有设置默认ttl

所以在GCDAsyncUdpSocket中的ttl1


设置ttl的方法为

选项IP_MULTICAST_TTL允许设置超时TTL,范围为0255之间的任何值,例如: 

unsigned char ttl=255;

setsockopt(s,IPPROTO_IP,IP_MULTICAST_TTL,&ttl,sizeof(ttl));


本地回环

GCDAsyncUdpSocket 没有设置本地回环

默认是开启本地回环的,因此对于GCDAsyncUdpSocket默认是会收到本地回环信息的。

设置本地回环的方法为:

默认情况下,当本机发送组播数据到某个网络接口时,在IP层,数据会回送到本地的回环接口,选项IP_MULTICAST_LOOP用于控制数据是否回送到本地的回环接口。例如:

unsigned char loop;

setsockopt(s,IPPROTO_IP,IP_MULTICAST_LOOP,&loop,sizeof(loop));


getsockopt() 获取参数


 //组播224.0.0.2地址,如果地址大于224的话,就要设置GCDAsyncUdpSocketTTL (默认TTL1

修改GCDAsyncUdpSocket源代码:

- (BOOL)performMulticastRequest:(int)requestType
                       forGroup:(NSString *)group
                    onInterface:(NSString *)interface
                          error:(NSError **)errPtr
{
	__block BOOL result = NO;
	__block NSError *err = nil;
	
	dispatch_block_t block = ^{ @autoreleasepool {
		
		// Run through sanity checks
		
		if (![self preJoin:&err])
		{
			return_from_block;
		}
		
		// Convert group to address
		
		NSData *groupAddr4 = nil;
		NSData *groupAddr6 = nil;
		
		[self convertNumericHost:group port:0 intoAddress4:&groupAddr4 address6:&groupAddr6];
		
		if ((groupAddr4 == nil) && (groupAddr6 == nil))
		{
			NSString *msg = @"Unknown group. Specify valid group IP address.";
			err = [self badParamError:msg];
			
			return_from_block;
		}
		
		// Convert interface to address
		
		NSData *interfaceAddr4 = nil;
		NSData *interfaceAddr6 = nil;
		
		[self convertIntefaceDescription:interface port:0 intoAddress4:&interfaceAddr4 address6:&interfaceAddr6];
		
		if ((interfaceAddr4 == nil) && (interfaceAddr6 == nil))
		{
			NSString *msg = @"Unknown interface. Specify valid interface by name (e.g. \"en1\") or IP address.";
			err = [self badParamError:msg];
			
			return_from_block;
		}
		
		// Perform join
		
		if ((socket4FD != SOCKET_NULL) && groupAddr4 && interfaceAddr4)
		{
			const struct sockaddr_in *nativeGroup = (struct sockaddr_in *)[groupAddr4 bytes];
			const struct sockaddr_in *nativeIface = (struct sockaddr_in *)[interfaceAddr4 bytes];
			
			struct ip_mreq imreq;
			imreq.imr_multiaddr = nativeGroup->sin_addr;
			imreq.imr_interface = nativeIface->sin_addr;
			
			int status = setsockopt(socket4FD, IPPROTO_IP, requestType, (const void *)&imreq, sizeof(imreq));
            
//            unsigned char ttl = 255;
//            status = setsockopt(socket4FD, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl));
            
            //参数loop设置为0禁止回送,设置为1允许回送
            //IP_MULTICAST_LOOP 禁止组播数据回送
            unsigned char loop = 0;
            setsockopt(socket4FD, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof(loop));
            
            int ttlRead;
            socklen_t lenTTL=sizeof(int);
            if((getsockopt(socket4FD, IPPROTO_IP, IP_MULTICAST_TTL, (char *)&ttlRead, &lenTTL)) == 0){
                printf("udp TTl Value is : %d/n", ttlRead);
            }
            
            int loopRead;
            socklen_t len = sizeof(int);
            if((getsockopt(socket4FD, IPPROTO_IP, IP_MULTICAST_LOOP, (char *)&loopRead, &len)) == 0){
                printf("udp loopRead Value is : %d/n", loopRead);
            }
            
			if (status != 0)
			{
				err = [self errnoErrorWithReason:@"Error in setsockopt() function"];
				
				return_from_block;
			}
			
			// Using IPv4 only
			[self closeSocket6];
			
			result = YES;
		}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值