2

我正在做一个客户端-服务器语音聊天程序(非托管 C++,win32),其中客户端使用 TCP 连接到服务器,文本聊天/聊天室功能在 TCP 中完成,而所有音频传输都通过单独的 UDP/RTP 套接字发送(使用 API来自 JRTPLIB)。

所以从TCP连接中知道IP,建立连接后就可以发送RTP套接字的端口号了。

问题是,在 TCP 中,自从您建立连接以来,只有服务器需要进行端口转发才能双向进行通信,而在 UDP 中,您必须使用 recvfrom() - afaik 需要在客户端的第一名,我不想要(如果您查看任何多人游戏或 VoIP 客户端,则不需要)

阅读有关 UDP Hole Punching 的资源(例如http://en.wikipedia.org/wiki/UDP_hole_punching),例如他们不断提到开始与服务器进行 udp 对话。就是这样 - 你如何在客户端不必打开任何端口的情况下实际与服务器启动 udp 对话(双向)?正如我所提到的,在 TCP 中,您只需要 connect() 到服务器,并且两种方式都可以进行通信。

另外——我知道 RTP 是基于 UDP 构建的,但是关于 RTP 打孔(再次使用 JRTPLIB),我还应该知道什么使其与 UDP 不同吗?

提前致谢!

4

1 回答 1

3

“打开端口”有两种可能的定义。一种是使用 bind() 为 UDP 或 listen() 为 TCP 打开一个端口,另一种是在防火墙中打开一个端口。

您需要使用 API 调用打开一个端口才能接收某些内容,没有办法绕过它,但您可能意识到这一点,所以我认为您的意思是在防火墙中打开一个端口。但是您不需要在发起通信的一方(客户端)执行此操作。这适用于 TCP 和 UDP,除非您的防火墙设置为非常偏执的模式。任何合理的防火墙都将允许服务器对 UDP 端口的响应,如果在某个时间之前有数据报从该端口发送到同一服务器。如果双方都在 NATing 防火墙/路由器后面,您只需要打孔。这就是 Skype 的做法。

此外,您甚至不必为 recvfrom() 之类的东西而烦恼。您可以只 bind() 一个 UDP 套接字,然后以与 TCP 完全相同的方式使用 connect() 和 recv()/send() 或 read()/write()。

于 2011-01-08T19:05:25.627 回答