2009-07-02 26 views
38

我需要一个将UDP数据包发送到某个网络服务器并接收响应的应用程序。服务器回复相同的请求来自的端口号,所以我首先需要绑定()我的套接字到任何UDP端口号。如何绑定到任何可用的端口?

硬编码的UDP端口号是一个坏主意,因为它可能是由同一台PC上运行的任何其他应用程序使用。

是否有可用的绑定的UDP套接字任何端口的方法是什么? IMO应该是快速获得空闲端口#的有效方式,该空闲端口被例如accept()函数。

如果不是,那么尝试绑定并检查WSAEADDRINUSE/EADDRINUSE状态的最佳策略是:从1025或1025 + rand()或其他某个端口顺序尝试端口?

+1

accept()用于基于连接的套接字,而不是数据报套接字。 – Beano

+1

也许这将有助于:http://serverfault.com/questions/447044 – yegor256

+0

在POSIX?还要求范围1024+:http://stackoverflow.com/questions/913501/how-to-let-kernel-choose-a-port-number-in-the-range-1024-5000-in-tcp-socket- pr –

回答

34

呼叫sendto没有调用bind第一,插座会自动绑定(自由港)。

+5

Downvoting只是因为正确的答案应该是@ Remy的一个(使用绑定中的端口0)。 – claf

+4

@claf隐式绑定也绑定,不是吗?在我看来,这两个答案都很有用。 – WGH

+0

@WGH:你是对的,这种行为记录的针对Windows套接字(注:如果一个套接字被打开,一个setsockopt调用制成,然后sendto调用制成,Windows套接字执行隐绑定函数调用),但我我不确定这是其他实现的情况。此外,我对隐性呼叫的看法是,这是一个坏习惯。 – claf

0

我必须失去了一些东西,你为什么不使用UDP套接字发回的数据? 从sendto开始,然后使用recvfrom函数读取传入数据,您也可以从中获取数据发送地址的奖励,在那里您可以发送回应。

+0

有些协议要求您关心您使用的端口号。例如,[TFTP](http://tools.ietf.org/html/rfc1350)客户端使用它来区分来自同一服务器的多个并发传输。服务器不能从同一端口发回,每个文件传输都需要服务器从不同的源端口发送。正如你所概述的那样,服务器确实会回复客户端的源地址和端口。 – doug65536

+1

在我的具体例子中,为每个传输使用一个新的套接字,然后盲目地执行'sendto'会隐式地选择一个源端口,但是在你实际执行sendto之前,可能会有其他协议关心端口号。 。 – doug65536

+0

@ doug65536这是一个有效的例子,但原来的问题没有包含任何具体细节的原因。 – Jonke

168

另一种选择是指定端口0至bind()。这将允许你绑定到一个特定的IP地址(如果你有安装多个),同时仍绑定到一个随机端口。如果您需要知道选择了哪个端口,则可以在执行绑定后使用getsockname()

+18

绑定到端口0是官方记录的绑定到操作系统分配的随机端口的方式。 –

+0

记录在哪里?我不是说这是错误的,我想看到一个权威性的声明。 –

+8

它在['bind()'](http://msdn.microsoft.com/en-us/library/windows/desktop/ms737550.aspx)文档中:“如果端口被指定为零,则服务提供程序从动态客户端端口范围为应用程序分配一个唯一端口在Windows Vista和更高版本上,动态客户端端口范围是一个介于49152和65535之间的值。这是从Windows Server 2003和更早版本开始的一个变化,是1025到5000之间的值......应用程序可以在调用bind之后使用getsockname来了解已分配给套接字的地址和端口。“ –

相关问题