Mac防火墙可以防止正确关闭多个多播UDP端口

时间:2012-08-09 02:57:35

标签: macos udp osx-lion ipfw

在我的Mac OSX 10.74上,我遇到了这种行为,我接近得出结论,这是Mac OSX防火墙软件中的一个错误。基本上,在应用程序退出后,会话期间使用的多播UDP端口除了一个之外没有关闭。

为了演示,我设置了两个应用程序。一个叫做UDPSender,它只向两个组播组发送两条消息。以下代码段可以从Mac或iOS设备运行。 GCDAsyncUdpSocket是最新版本。

GCDAsyncUdpSocket *udpSocket1;
GCDAsyncUdpSocket *udpSocket2;
udpSocket1 = [[GCDAsyncUdpSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
udpSocket2 = [[GCDAsyncUdpSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
NSData *data = [@"A test message from socket1" dataUsingEncoding:NSUTF8StringEncoding];
[udpSocket1 sendData:data toHost:@"239.1.1.110" port:46110 withTimeout:-1 tag:1];
data = [@"A test message from socket2" dataUsingEncoding:NSUTF8StringEncoding];
[udpSocket2 sendData:data toHost:@"239.1.1.120" port:46120 withTimeout:-1 tag:1];

我为Mac创建了另一个名为UDPReceiver的应用程序。 (这是行为不端的人)

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    // Insert code here to initialize your application
    GCDAsyncUdpSocket *udpSocket1;
    GCDAsyncUdpSocket *udpSocket2;
    udpSocket1 = [[GCDAsyncUdpSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
    udpSocket2 = [[GCDAsyncUdpSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
    NSError *error = nil;

    // udpSocket1
    if ([udpSocket1 bindToPort:46110 error:&error])
    {
        if (![udpSocket1 joinMulticastGroup:@"239.1.1.110" error:&error])
        {
            NSLog(@"udpSocket1 multicast failed to multicast group");
        }
        if (![udpSocket1 beginReceiving:&error])
        {
            [udpSocket1 close];
            NSLog(@"udpSocket1 rrror starting server (recv): %@", error);
        }
    } else  
    {
        NSLog(@"udpSocket1 rrror starting server (bind): %@", error);
        //        return;
    }

    // udpSocket2
    if ([udpSocket2 bindToPort:46120 error:&error])
    {
        if (![udpSocket2 joinMulticastGroup:@"239.1.1.120" error:&error])
        {
            NSLog(@"udpSocket2 multicast failed to multicast group");
        }
        if (![udpSocket2 beginReceiving:&error])
        {
            [udpSocket2 close];
            NSLog(@"udpSocket2 rrror starting server (recv): %@", error);
            return;
        }
    } else 
    {
        NSLog(@"udpSocket2 rrror starting server (bind): %@", error);
        //        return;
    }

}

- (void)udpSocket:(GCDAsyncUdpSocket *)sock didReceiveData:(NSData *)data
      fromAddress:(NSData *)address
withFilterContext:(id)filterContext
{
    NSString *msg = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    NSLog(@"Receiving: %@", msg);
}

测试序列如下:打开Mac的防火墙。启动UDPReceiver,启动UDPSender。在UDPReceiver机器上,Mac的防火墙提示输入权限...选择允许。结果是两个正确的日志语句:

2012-08-07 19:56:53.594 UDPReceiver[290:403] Receiving: A test message from socket1
2012-08-07 19:56:53.595 UDPReceiver[290:403] Receiving: A test message from socket2

接下来,关闭UDPReceiver,然后重新打开UDPReceiver。马上,你会看到这个日志。

2012-08-07 19:39:13.639 UDPReceiver[810:403] udpSocket1 rrror starting server (bind): Error Domain=NSPOSIXErrorDomain Code=48 "Address already in use" UserInfo=0x7fc7b3109d20 {NSLocalizedDescription=Address already in use, NSLocalizedFailureReason=Error in bind() function}

如果此时重启UDPSender,您将看到其他日志输出:

2012-08-07 19:39:29.939 UDPReceiver[810:403] Receiving: A test message from socket2

我打开Mac终端并使用此命令查看活动端口:netstat -anf inet。第一张照片是UDPReceiver第一次被执行。第二张照片是在UDPReceiver关闭之后。

我发现有两种方法可以解决这个问题:

  1. 重启我的Mac。然后它将再次正常工作。但上述症状仍然存在。
  2. 完全关闭防火墙。这将完全消除这个问题。
  3. 之前有没有人遇到过这种现象?有任何建议如何(编程)解决这个问题吗?

    enter image description here

    enter image description here

0 个答案:

没有答案