Sockets 如何获得免费的套接字端口?C++;

Sockets 如何获得免费的套接字端口?C++;,sockets,udp,port,Sockets,Udp,Port,我正在编写一个UDP测试客户端/服务器,我想让它通过防火墙。假设我需要做的就是让双方都发送到正确的IP和服务器。获取IP不是问题,但是如何让客户端选择一个随机空闲端口并向用户报告?我最终希望它连接到matchmaker服务器,但现在我需要一个简单的工作原型,我想输入端口号,以便我的朋友/测试人员可以通过IM向我发送#以便我们可以测试 如何获取端口号? 抱歉这么长时间的描述。我注意到当我不描述时,人们告诉我不要做我要求的事情:(一般来说,作为开发人员,您可以选择端口。您可以将应用程序设置为从配置文

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

如何获取端口号?
抱歉这么长时间的描述。我注意到当我不描述时,人们告诉我不要做我要求的事情:(

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

如果我正确理解了您的问题,我不确定是否有办法通过编程实现您的目标(即使有,我也不认为这是正确的方法)。我认为您需要找到一个在服务器机器上未使用的端口(如果通信是双向的,则可能是客户端机器上的不同或相同端口),并且该端口必须能够通过防火墙。我假设“获得IP不是问题",您已将防火墙配置为将某些或所有端口转发到防火墙内的特定计算机?如果是,则您所寻找的端口是您转发的端口之一。只要该端口上没有运行其他服务,您可以选择任意端口。1024以下的端口是保留的,因此您可能希望选择比1024以下端口更高的端口数在。您可以使用一个简单的端口扫描工具,例如查看您的计算机上正在哪些端口上运行哪些服务,然后选择一个不同的端口。请注意,
nmap
在创建套接字时可能会被防火墙和各种
bind
规则所愚弄。

我认为您最好选择一个固定端口,而不是依赖随机端口O/S选择的端口号


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

如果使用WINSOCK,请检查以下链接:
基本上,您有两种选择:将端口设置为0,然后让系统为您分配一个端口,或者选择一个随机端口。如果无法打开套接字,请尝试另一个端口(请确保避开保留端口)

使用高度技术性的术语,这实际上是一个非常棘手的问题,甚至是一对棘手的问题。根据防火墙的配置,它通常允许来自IP端点上另一个端点的响应,因为请求来自。因此…如果您的朋友使用类似于
recvfrom()的东西接收UDP数据报
系统调用时,address参数将接收要响应的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地址及其选择使用的端口号。您在代码中指定的端口号可能与您的朋友必须向其发送数据的端口号完全不同。最终,您选择的端口可能无关紧要选择使用,因为防火墙可能在一个完全不同的端口上发送和接收,这就是全部内容。我建议阅读一些关于如何克服这一障碍的提示

IMHO的最佳方法是:

  • 让操作系统通过使用零端口号调用或跳过绑定来选择端口
  • 让客户端从套接字层接收地址信息(例如,第五个和第六个参数到)
  • 客户端将响应发送到上一步中检索到的端点
  • 调整防火墙配置,直到前面的步骤起作用
  • 当然,所有的魔法都在最后一步。如果你可以禁用NAT或确保防火墙永远不会切换端口,那么锁定端口号并绑定到它也会起作用。你可能想看看
    %WINDIR%\system32\drivers\etc\services
    (或
    /etc/services
    ,具体取决于您的操作系统倾向),以了解保留的或通常使用的端口号。

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