【发布时间】:2014-01-06 18:35:31
【问题描述】:
我正在使用GCDAsyncUdpSocket 打开一个 UDP 套接字,然后我将它绑定到一个端口。该类只是普通 POSIX 套接字调用(如 socket、bind 等)的包装器。
场景 1:
- MyMacBook:启动进程 A
- MyMacBook:打开 UDP 端口 23141 => 成功
- SomeComputer:将 UDP 数据包发送到 MyMacBook,端口 23141
- MyMacBook:标准 OSX 防火墙询问我是否要允许传入网络连接,我同意。
- MyMacBook:忽略数据包,不要读取它。 (或者至少,我没有看到一条日志消息告诉我我收到了一个数据包。要么我的代码坏了,要么 CocoaAsyncSocket 代码坏了,要么操作系统没有向我的程序报告数据包。)
- MyMacBook:杀死进程 A
- MyMacBook:启动进程 A
- MyMacBook:打开 UDP 端口 23141 => 失败:
Error Domain=NSPOSIXErrorDomain Code=48 "Address already in use" UserInfo=0x100407f30 {NSLocalizedDescription=Address already in use, NSLocalizedFailureReason=Error in bind() function
为什么???
netstat -n |grep 2314
udp4 626 0 *.23146 *.*
udp4 1251 0 *.23141 *.*
^^这是外壳上损坏的 UDP 端口的样子。如果我想再次使用该端口号,我似乎必须重新启动我的机器:-(
不,我没有阻塞端口的旧进程。我检查了ps aux 和lsof -i | grep UDP。
场景 2:
- MyMacBook:启动进程 A
- MyMacBook:打开 UDP 端口 23143 => 成功
- MyMacBook:杀死进程 A
- MyMacBook:启动进程 A
- MyMacBook:打开 UDP 端口 23143 => 成功
- MyMacBook:杀死进程 A
- MyMacBook:启动进程 A
- MyMacBook:打开 UDP 端口 23143 => 成功
- MyMacBook:杀死进程 A
- ...
如果端口从未使用过,系统不会在意我是否关闭它。应该是这样的。
我的问题:
这里有什么问题?当然,在一个完美的世界中,程序不会崩溃,并且套接字都使用 POSIX close 函数关闭。在一个不完美的世界里,我只需要输入 Cmd-。在 XCode 中杀死我正在开发的应用程序,并且不会调用 close。
当我试图将我的套接字绑定到 UDP 端口时,我真正想对操作系统说的是:“请 OSX 10.8.5,将我的套接字绑定到端口 23141。如果其他程序打开了它当前并且正在监听,那么你可能会告诉我该端口正在使用中,但是如果没有正在运行的程序关心这个端口,那么让我将它绑定到端口 23141!!”这是一个 OSX 错误吗?这是新的吗?它是记录在案的已知错误,还是所谓的“功能”?
【问题讨论】:
-
lsof -i :23141说什么?它应该显示正在使用该端口的进程。 -
我的猜测是,在场景 1 中,您正在生成一个继承套接字的后台进程,并且当您杀死进程 A 时它不会被杀死。
-
无输出,退出代码 1。
lsof -i | grep UDP没有列出我的端口号,也没有列出打开它的程序。netstat -n | grep 23141显示udp4 1563 0 *.23141 *.*,这对我来说似乎很愚蠢。ps aux没有列出我的应用程序。 -
@Barmar:我不产生任何进程,我不打电话给
fork。我虽然使用 dispatch_queues。但我确信当我按下 Cmd- 时它们会被杀死。在 XCode 中。 -
好像以前见过这样的:superuser.com/questions/504750/…那里也没有解决办法
标签: c macos sockets networking udp