运行服务器进程时,动态获取C中未使用的端口号

时间:2011-09-23 15:47:59

标签: c linux sockets

我正在使用C并编写客户端 - 服务器程序,我希望获得一个未使用的端口号来运行我的服务器进程。我的服务器代码是这样的:

getaddrinfo()
socket()
bind()
listen
while(1)
  accept()

我需要为bind()调用提供未使用的端口addr。但是我不希望在启动服务器进程时通过命令行传递端口号。端口号应该通过套接字调用获得,我需要使用它来启动我的客户端进程。是否有任何套接字调用可以帮助我在C中动态获取未使用的端口?

4 个答案:

答案 0 :(得分:8)

在sockaddr_in中将socket设置sin_port绑定()为0。系统会自动选择未使用的端口。您可以通过调用getsockname()来检索它。

但我不知道如何将它传递给客户端,除了打印它并将其用作客户端程序的命令行参数。

答案 1 :(得分:1)

这将是一个巨大的race condition。想象一下这一系列事件:

  1. 您的代码使用(不存在的)getNextFreePort()调用。
  2. 另一个进程在没有指定端口的情况下创建一个新套接字,获取"您的"分配给它的号码。
  3. 您尝试使用&{34;地址在使用"时失败bind()
  4. 这就是为什么服务器往往拥有众所周知的"地址,因为客户需要知道它应该连接的位置。

    此外,除非我误解,否则您似乎希望客户端在启动时能够调用getNextFreePort(),然后神奇地获取服务器已经的端口号得到了,用过了吗?这并没有多大意义,所以我希望我误解你。

答案 2 :(得分:1)

由于您使用的是Linux / Unix,这正是RPC portmapper旨在解决的问题。您的服务器bind()到未使用的端口(端口0),然后注册生成的实际端口(使用getsockname()通过应用程序/服务名称获取端口映射程序。

客户端然后在其已知端口上查询portmapper,询问命名服务实际运行的端口。

portmapper RPC不像以前那样受欢迎

如果服务器和客户端位于同一个框中:

另一种方法是为共享文件使用某种命名方案(创建临时文件/tmp/servport.xxxxx),用端口替换xxxxx。

或者您可以创建服务器将其端口存入的共享内存段。客户端将连接到相同的共享内存,读取端口,并正常连接。

或者您的服务器可以在已知/共享路径上创建一个unix域套接字,客户端可以连接到该套接字,询问服务器所在的端口。 (显然,如果他们都是本地的话,你可以这样做所有的IPC!)

IPC有很多选择...

答案 3 :(得分:0)

如果你将()绑定到一个随机或不可预测的地址+端口号,客户端可能会遇到一些难以找到你的服务器并连接到它。