问题描述
我正在做一个客户端-服务器语音聊天程序(非托管 C++,win32),其中客户端使用 TCP 连接到服务器,文本聊天/聊天室功能在 TCP 中完成,而所有音频传输都通过单独的 UDP/RTP 套接字发送(使用 JRTPLIB 的 API).
I am doing a client-server voice chat program(unmanaged C++,win32) in which clients connects to the server using TCP and textchat/chatroom functions are done in TCP while all audiotransmission is sent through a separate UDP/RTP socket (using the API from JRTPLIB).
所以从TCP连接知道IP,建立连接后就可以发送RTP套接字的端口号了.
So the IP is known from the TCP connection, and the port number of the RTP socket can be sent after connection is established.
问题在于,在 TCP 中,自从您建立连接以来,只有服务器需要进行端口转发才能进行双向通信,而在 UDP 中,您必须使用 recvfrom() - afaik 需要端口首先在客户端打开,这是我不想要的(如果您查看任何多人游戏或 VoIP 客户端,则不需要)
The problem is that in TCP only the server needs to do port forwarding for communications to work both ways since you establish a connection, while in UDP you'd have to use recvfrom() -- which afaik needs the ports to be opened in the first place on the client side, which I do not want (and is not needed if you look at any multiplayer game or VoIP client)
阅读有关 UDP 打孔的资料(例如 http://en.wikipedia.org/wiki/UDP_hole_punching),例如他们不断提到开始与服务器的 udp 对话.就是这样 - 你如何在客户端不必打开任何端口的情况下实际与服务器启动 udp 对话(双向)?在 TCP 中,正如我所提到的,您只需要 connect() 到服务器,就可以通过两种方式进行通信.
Reading on sources that talk about UDP Hole Punching (for example http://en.wikipedia.org/wiki/UDP_hole_punching) for example they keep mentioning starting a udp conversation with the server. That's the thing - how do you actually start a udp conversation(both ways) with the server without the client having to open any ports? in TCP as I mentioned you just need to connect() to the server and communication is possible both ways.
另外——我知道 RTP 是基于 UDP 构建的,但是关于 RTP 打孔(同样,使用 JRTPLIB)还有什么我应该知道的与 UDP 不同的吗?
Also -- I know RTP builds on UDP but is there anything else I should know about the RTP hole punching (again, using JRTPLIB) that makes it differ from UDP?
提前致谢!
推荐答案
开放端口"有两种可能的定义.一种是用 bind() 为 UDP 或 listen() 为 TCP 打开一个端口,另一种是在防火墙中打开一个端口.
There are two possible definitions of "opening a port". One is opening a port with bind() for UDP or listen() for TCP, another one is opening a port in a firewall.
您需要通过 API 调用打开一个端口才能接收某些内容,没有办法绕过它,但您可能意识到这一点,所以我认为您的意思是在防火墙中打开一个端口.但是您不需要在发起通信的一方(客户端)执行此操作.这适用于 TCP 和 UDP,除非您的防火墙设置为非常偏执的模式.任何合理的防火墙都将允许服务器对 UDP 端口的响应,如果在某个时间之前有数据报从该端口发送到同一服务器.如果双方都在 NATing 防火墙/路由器后面,您只需要打孔.这就是 Skype 的做法.
You need to open a port with an API call in order to receive something, there is no way around it, but you probably realize this, so I think you mean opening a port in a firewall. But you don't need to do this on the side that initiates communication (the client). This applies both to TCP and UDP, unless your firewall is set up in a very paranoid mode. Any reasonable firewall would allow a response from a server to a UDP port if there was a datagram sent from this port to the same server some time before. You only need hole punching if both sides are behind NATing firewalls/routers. That's how Skype does it.
此外,您甚至不必为 recvfrom() 之类的东西操心.您可以只 bind() 一个 UDP 套接字,然后使用 connect() 和 recv()/send() 或 read()/write(),就像使用 TCP 一样.
Moreover, you don't even have to bother with recvfrom() and such stuff. You can just bind() a UDP socket, then use connect() and recv()/send() or read()/write() exactly in the same way as you'd do with TCP.
这篇关于c++ 打孔UDP(RTP)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!