2012-12-12 64 views
1

stackoverflow用户!UDP穿孔(C++/winsock)

我有一个应用程序必须处理p2p,这就是我如何获得UDP Hole punching。但是我遇到了实施麻烦。希望,你可以给我一些提示。

我有服务器,它工作完美,并介绍客户端彼此,但客户端无法连接,可能是因为我的小型exp与套接字工作。因此,客户端ALGO是:

  1. 创建UDP套接字(插座(AF_INET,SOCK_DGRAM,IPPROTO_UDP);)通过SENDTO功能
  2. 使用recvfrom的更衣室功能
  3. 信息发送到服务器从服务器获得答案

经过这3个步骤后,我获得了对等端点。接下来,我想客户端连接方式有两种:

WAY1

  1. 使用同样的套接字发送数据通过同行的sendto功能,但通过另一个SOCKADDR
  2. recvfrom更衣柜功能(并在那一点我得到WSAECONNRESET错误)

Way2

  1. 创建新的socket
  2. 将其绑定
  3. 用它来发送数据同行

在这样一个客户端上绑定失败和另一个错误地收听WSAEADDRINUSEWSAECONNRESET。我明显做错了事,你的帮助将不胜感激。提前致谢。

P.S.想分享UDP打孔的好文章,以帮助那些谁是新的这种技术:http://www.brynosaurus.com/pub/net/p2pnat/

+0

试着看看这个问题:http://stackoverflow.com/questions/8819118/tcp-hole-punching 尽管用UDP做这件事一定比较容易 – Giann

回答

2

如果read the documentationrecvfrom(),它说:

WSAECONNRESET

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

这意味着您致电sendto()失败。如果一个或两个客户端位于路由器后面,这是有道理的。根据你的描述(以及缺少代码),你实际上并没有进行任何打洞工作来打开路由器以允许客户端到客户端的数据包通过。您只向服务器发送了一条消息,它允许客户端到服务器和服务器到客户端的数据包通过。如在article you linked to中详细描述的那样,每个客户端和服务器之间需要更多的数据包交换来在每个端部执行打孔。你是否真的在做文章所说的事情?

+0

你是什么意思“你没有真正执行任何打孔“?对于UDP打孔,根据文章和wiki,我需要2个客户端和服务器。客户端连接到服务器,服务器在客户端之间共享其公共/私有端点。在下一步中,客户端必须使用这些端点直接发起连接。首先发送的数据包将被peer2的NAT拒绝,但会在peer1的NAT中“打孔”。之后,peer2可以连接peer1。 – JacksonRR

+0

@JacksonRR:我错过了将客户连接在一起的部分。不过,我认为这是正确的行为。 'recvfrom()'中的'WSAECONNRESET'告诉你在同一套接字上的前一个'sendto()'失败,这就是你想要的。 'sendto()'不能报告失败。一旦打孔后,后续发送将成功。您应该将多个数据包发送到多个地址以正确打孔。你是在第一次失败之后停下来的吗?如果'recvfrom()'报告'sendto()'失败,那么它不是错误,只需尝试下一个冲突步骤。 –

+0

感谢您的回复。我试图发送更多的数据报,忽略第一个错误,但仍然没有好的结果。 recvfrom func锁定应用程序并忽略其他对等方发送的所有数据包,即使此对等方将外发数据包发送到打孔:/ – JacksonRR