我正在使用C并编写客户端 - 服务器程序,我希望获得一个未使用的端口号来运行我的服务器进程。我的服务器代码是这样的:
getaddrinfo()
socket()
bind()
listen
while(1)
accept()
我需要为bind()调用提供未使用的端口addr。但是我不希望在启动服务器进程时通过命令行传递端口号。端口号应该通过套接字调用获得,我需要使用它来启动我的客户端进程。是否有任何套接字调用可以帮助我在C中动态获取未使用的端口?
答案 0 :(得分:8)
在sockaddr_in中将socket设置sin_port绑定()为0。系统会自动选择未使用的端口。您可以通过调用getsockname()来检索它。
但我不知道如何将它传递给客户端,除了打印它并将其用作客户端程序的命令行参数。
答案 1 :(得分:1)
这将是一个巨大的race condition。想象一下这一系列事件:
getNextFreePort()
调用。bind()
。这就是为什么服务器往往拥有众所周知的"地址,因为客户需要知道它应该连接的位置。
此外,除非我误解,否则您似乎希望客户端在启动时能够调用getNextFreePort()
,然后神奇地获取服务器已经的端口号得到了,用过了吗?这并没有多大意义,所以我希望我误解你。
答案 2 :(得分:1)
由于您使用的是Linux / Unix,这正是RPC portmapper旨在解决的问题。您的服务器bind()
到未使用的端口(端口0),然后注册生成的实际端口(使用getsockname()
通过应用程序/服务名称获取端口映射程序。
客户端然后在其已知端口上查询portmapper,询问命名服务实际运行的端口。
portmapper RPC不像以前那样受欢迎
如果服务器和客户端位于同一个框中:
另一种方法是为共享文件使用某种命名方案(创建临时文件/tmp/servport.xxxxx),用端口替换xxxxx。
或者您可以创建服务器将其端口存入的共享内存段。客户端将连接到相同的共享内存,读取端口,并正常连接。
或者您的服务器可以在已知/共享路径上创建一个unix域套接字,客户端可以连接到该套接字,询问服务器所在的端口。 (显然,如果他们都是本地的话,你可以这样做所有的IPC!)
IPC有很多选择...
答案 3 :(得分:0)
如果你将()绑定到一个随机或不可预测的地址+端口号,客户端可能会遇到一些难以找到你的服务器并连接到它。