我正在创建一个 BSD 套接字,socket
然后尝试listen
使用它。当防火墙处于活动状态时,调用 会listen
导致应用程序防火墙对话框出现,但它消失得太快,用户无法与之交互。我发现调用 to 的任何延迟listen
,例如在调试器中添加断点或调用 to sleep
,在调用之后socket
都会导致对话框出现并保持足够长的时间让用户与之交互。如果在用户可以选择任何内容之前对话框消失了,防火墙会拒绝该应用程序的所有后续传入请求。
有谁知道是什么导致对话框消失,以及是否有比调用更合适的方法来防止它sleep
?
如果有人想尝试重现此问题,我将在下面附上导致此行为的代码。如果waitForUserInput
为真,对话框将出现并一直持续到套接字关闭。如果不是真的,对话会在一瞬间消失。如果您在测试的行上添加断点,waitForUserInput
即使该变量是 .它也会显示 5 秒的对话框NO
。在所有这些情况下,调用listen
不会返回错误。我正在使用 OS X 10.7.4 和 Xcode 4.2 。
#import <sys/socket.h>
#import <netdb.h>
static void firewallDialog(BOOL waitForUserInput){
struct addrinfo *res, *p, host;
memset(&host, 0, sizeof host);
host.ai_family = AF_UNSPEC; // no preference for IP4/6
host.ai_socktype = SOCK_STREAM; // TCP
host.ai_flags = AI_PASSIVE; // local IP address
if(-1 != (getaddrinfo(NULL,"1234",&host,&res))){
int sock = -1;
for(p = res; p != NULL; sock = -1, p = p->ai_next) {
// make a socket
if(-1 == (sock = socket(p->ai_family, p->ai_socktype, p->ai_protocol))){
continue;
}
if(p->ai_family == PF_INET6){
((struct sockaddr_in6*)p->ai_addr)->sin6_addr = in6addr_any;
}
if(-1 == bind(sock, p->ai_family == PF_INET ? INADDR_ANY : p->ai_addr, p->ai_addrlen)){
close(sock);
continue;
}
break;
}
freeaddrinfo(res);
if(-1 != sock){
if(waitForUserInput){ sleep(1); }
if(-1 == listen(sock, 20)){
close(sock);
}else{
NSLog(@"Call to listen was successful");
sleep(5);
close(sock);
}
}
}
}