我正在使用UDT库将文件传输到NAT后面的计算机。我已经在python中做了一个打孔协议,我知道它是如何工作的。 在这里,我正在尝试将UDT套接字绑定到现有的UDP套接字。
int udt_holepunching(SOCKET sock, SOCKADDR_IN sin, int size, SOCKADDR_IN peeraddr)
{
UDTSOCKET u;
bool rdv = true;
UDT::setsockopt(u, 0, UDT_RENDEZVOUS, &rdv, sizeof(bool));
UDT::bind(u, sock);
UDT::connect(u, &peeraddr, sizeof(peeraddr));
}
sock
我现有的UDP套接字
和peeraddr
我要谈的电脑的地址
我有这个错误:
client.cpp: In function ‘int udt_holepunching(SOCKET, SOCKADDR_IN, int, SOCKADDR_IN)’:
client.cpp:29:20: error: invalid conversion from ‘SOCKET {aka int}’ to ‘const sockaddr*’ [-fpermissive]
UDT::bind(u, sock);
^
client.cpp:29:20: error: too few arguments to function ‘int UDT::bind(UDTSOCKET, const sockaddr*, int)’
In file included from client.cpp:13:0:
../src/udt.h:315:13: note: declared here
UDT_API int bind(UDTSOCKET u, const struct sockaddr* name, int namelen);
这有点奇怪,因为在UDT bind documentation中,它似乎是可能的。
答案 0 :(得分:0)
链接到引用显示两个重载。编译器选择第一个(树参数重载),因为您传递UDTSOCKET
作为第一个参数并且具有第二个参数。
由于三参数重载中的第二个参数不是SOCKET
,因此会出现第一个错误。而且,由于您只将两个参数传递给期望三个的函数,因此会出现第二个错误。
如果要绑定到特定地址(比如传递给函数的sin
参数),则需要将指向该地址结构的指针作为第二个参数传递,并将该结构的大小作为第三个论点:
UDT::bind(u, (const SOCKADDR*) &sin, sizeof(sin));
如果您想使用第二个重载,请使用它:
UDT::bind(sock);
你不能随意混合搭配,你必须选择其中一个。
答案 1 :(得分:0)
技术答案隐藏在上面的评论中: 使用
bind2(udtsocket, udpsocket)
关于创建的 UDT/UDP 套接字。
关于打孔,这可能完全不考虑UDP,见 UDT Hole Punching Pattern。这也显示了 RENDEVOUS 选项的有效使用。
这种情况下的UDT需要唯一的连接,即你要么连接到会合服务器,要么与另一个节点处于P2P模式;这是建立多个独立 P2P 连接序列的唯一正确方法。
引用的“UDT Hole Punching Pattern”中不完美的是,UDT套接字绑定到固定参数地址;最好是将socket绑定到端口0。系统会分配一个合适的动态端口,可以通过getsockname()
检索,然后在P2P模式下重新使用。