在运行服务器进程时dynamic获取C中未使用的端口号

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

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

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

只需将sockaddr_in中的套接字设置sin_port绑定到0即可。 系统会自动选择未使用的端口。 你可以通过调用getsockname()来获取它。

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

这将是一个巨大的竞争条件 。 想象一下这一系列事件:

  1. 你的代码使用(不存在的) getNextFreePort()调用。
  2. 另一个进程创建一个新的套接字,而不指定端口,获得分配给它的“你的”号码。
  3. 您尝试bind() ,这与“使用中的地址”失败。

这就是服务器倾向于拥有“知名”地址的原因,因为这是为了使客户端知道应该连接的位置。

另外,除非我误会,否则您似乎期望客户端能够在启动时调用getNextFreePort() ,然后奇迹般地获取服务器已经获得的端口号并使用? 这没有什么意义,所以希望我误解了你。

由于你在Linux / Unix上,这正是RPC portmapper设计要解决的问题。 您的服务器bind()到一个未使用的端口(端口0),然后通过应用程序/服务名称将由此生成的实际端口(通过getsockname()与portmapper进行注册。

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

portmapper RPC不像以前那样受欢迎

如果服务器和客户机在同一个机器上:

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

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

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

很多IPC的选择…

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