UDP打孔(c ++ / winsock)

时间:2012-12-12 16:54:54

标签: c++ udp winsock p2p hole-punching

stackoverflow用户!

我有一个必须处理p2p的应用程序,这就是我如何进行UDP Hole打孔。但是我遇到了实施方面的麻烦。希望,你可以给我一些提示。

我有服务器,它工作得很完美并且将客户端介绍给彼此,但客户端无法连接可能是因为我的小型exp使用套接字。所以,客户算法是:

  1. 创建udp套接字(套接字(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
  2. 通过 sendto 功能
  3. 向服务器发送消息
  4. 使用 recvfrom 锁定功能从服务器
  5. 获取答案

    在这3个步骤之后,我获得了对等端点。接下来,我试图以两种方式连接客户端:

    WAY1

    1. 使用相同的套接字通过 sendto 功能向对等方发送数据,但传递另一个 sockaddr
    2. 使用 recvfrom 锁定功能进行收听(此时我收到 WSAECONNRESET 错误)
    3. Way2

      1. 创建新套接字
      2. 绑定它
      3. 使用它向同行发送数据
      4. 收听
      5. 通过这种方式,一个客户端无法进行绑定,另一个客户端无法通过错误 WSAEADDRINUSE WSAECONNRESET 进行侦听。我显然做错了什么,你的帮助将受到高度赞赏。提前谢谢。

        P.S。想要分享一篇关于UDP打孔的好文章,以帮助那些对这种技术不熟悉的人:http://www.brynosaurus.com/pub/net/p2pnat/

1 个答案:

答案 0 :(得分:2)

如果recvfrom()sendto(),则表示:

  

WSAECONNRESET

     

虚拟电路由远程端执行硬关闭或中止关闭重置。应用程序应关闭套接字;它不再可用。 在UDP数据报套接字上,此错误表示先前的发送操作导致ICMP端口无法访问消息

这意味着您对{{1}}的调用失败。如果一个或两个客户端都在路由器后面,这是有道理的。根据您的描述(以及缺少代码),您实际上并没有执行任何打孔来打开路由器以允许客户端到客户端数据包通过。您只向服务器发送了一条消息,允许客户端到服务器和服务器到客户端的数据包通过。每个客户端和服务器之间需要进行一些数据包交换,以便在每一端执行打孔,如read the documentation中所述。你真的在做文章所说的事吗?