4

我正在编写一个 UDP 测试客户端/服务器,我想通过防火墙获取它。据说我需要做的就是让双方都发送到正确的 IP 和服务器。获取 IP 不是问题,但我如何让客户端随机选择一个空闲端口并将其报告给用户?我最终希望它连接到媒人服务器,但现在我需要一个简单的工作原型,我想计算端口号,以便我的朋友/测试人员可以通过 IM 向我发送 #,以便我们进行测试。

我如何获得端口号?对不起,很长的描述。我注意到人们告诉我当我不提供 desc 时不要做我要求的事情:(

4

6 回答 6

5

用专业术语来说,这实际上是一个非常棘手的问题,甚至是一对令人讨厌的问题。根据防火墙的配置,当请求来自时,它通常会允许来自 IP 端点上的另一个端点的响应。所以...如果您的朋友使用recvfrom()系统调用之类的方式接收 UDP 数据报,则地址参数将接收 IP 端点信息以进行响应。因此,另一端应该能够sendto()使用相同的寻址信息进行响应。就像是:

/* initiator */
struct sockaddr_in hisaddr;
memset(&hisaddr, 0, sizeof(hisaddr));
hisaddr.sin_addr.s_addr = htonl(target_ip);
hisaddr.sin_port = htons(target_port);
sendto(sd, msg_ptr, msg_sz, 0, (struct sockaddr*)&hisaddr, sizeof(hisaddr));

/* receiver */
struct sockaddr_in peeraddr;
socklen_t peer_sz = sizeof(peeraddr);
recvfrom(sd, buf_ptr, buf_sz, 0, (struct sockaddr*)&peeraddr, &peer_sz);
/* build response */
sendto(sd, msg_ptr, msg_sz, 0, (struct sockaddr*)&peeraddr, peer_sz);

peeraddr一边将是您的外部地址,或者更准确地说,是您的防火墙的 IP 地址和它选择使用的端口号。您在代码中指定的端口号可能与您的朋友必须向其发送数据的端口完全不同。最终,您选择使用哪个端口可能并不重要,因为防火墙可能在完全不同的端口上发送和接收 - 这就是网络地址转换的全部内容。我建议阅读RFC3235,了解如何克服这一障碍的一些技巧。

恕我直言,最好的方法是:

  1. 让操作系统通过使用bind()零端口号调用或完全跳过绑定来选择端口
  2. 让客户端从套接字层接收地址信息(例如, 的第五个和第六个参数recvfrom()
  3. 客户端向上一步中检索到的端点发送响应
  4. 调整防火墙配置,直到前面的步骤有效

当然,所有的魔法都在最后一步。如果您可以禁用 NAT 或确保防火墙永远不会切换端口,那么确定一个端口号并bind对其进行 -ing 也将起作用。您可能需要查看%WINDIR%\system32\drivers\etc\services(或/etc/services取决于您的操作系统倾向)以了解保留或通常使用的端口号。

于 2009-04-29T16:38:36.673 回答
1

在发送数据之前绑定()套接字。为 bind() 指定端口 0,操作系统将为您选择一个未使用的端口。然后,您可以使用 getsockname() 来找出 wsa 选择的端口。

于 2009-07-10T01:13:21.557 回答
0

一般来说——你——作为开发者——选择端口。您可以将您的应用程序设置为从配置文件或用户输入读取端口 - 但没有魔法防火墙会告诉您使用哪个端口......

于 2009-04-29T16:04:20.263 回答
0

如果我正确理解了您的问题,我不确定是否有办法以编程方式执行您想要的操作(即使有,我认为这不是正确的方法)。我认为您需要找到服务器计算机上未使用的端口(如果通信是双向的,则可能是客户端计算机上的不同或相同端口)并且该端口必须能够通过您的防火墙. 我假设既然您说“获取 IP 不是问题”,您已经将防火墙配置为将部分或所有端口转发到防火墙内的特定计算机?如果是这样,您寻求的端口就是您转发的端口之一。只要该端口上没有运行其他服务,您就可以选择任意一个。低于 1024 的端口是保留的,因此您可能想要选择一个更高的数字。nmap以查看哪些服务在您的计算机上的哪些端口上运行并选择不同的。请注意,创建套接字时nmap可能会被防火墙和各种规则所欺骗。bind

于 2009-04-29T16:05:03.663 回答
0

我认为你最好选择一个固定端口,而不是依赖操作系统选择的随机端口号。

如果您使用随机端口,则每次运行程序时都必须更改防火墙设置。

于 2009-04-29T16:05:24.443 回答
0

如果您使用的是 WINSOCK,请检查此链接: http: //msdn.microsoft.com/en-us/library/aa280717 (VS.60).aspx 基本上您有 2 个选择,将端口设置为 0 并让系统为您分配一个或随机选择一个尝试打开套接字,如果它不起作用尝试另一个(一定要避开保留的端口)

于 2009-04-29T16:06:19.573 回答