Indy UDP通信IP/端口混淆:RTP音频收发双向配置困惑
问题解答
核心结论:接收端RTP接收器的端口选择
最可靠的方式是让接收端用同一个UDP端口同时发送"startrtp"命令和接收RTP数据,这样能直接利用路由器NAT自动建立的双向通道,不需要额外的端口转发或信息交换。
针对你的具体问题的解答
1. 发送端是否需要回复PeerIP和PeerPort给接收端?
不需要。只要接收端用同一个端口发命令和收RTP:
- 发送端的命令UDP服务器收到"startrtp"包时,能通过
AThread.Binding.PeerIP和AThread.Binding.PeerPort直接获取接收端的IP和端口(也就是接收端用来收RTP的端口) - 接收端自己明确知道这个端口(因为是你绑定的固定端口),直接让RTP接收器监听这个端口即可,不需要发送端额外回复。
如果接收端非要分开用两个不同的端口(一个发命令,一个收RTP),那必须在"startrtp"命令里附带接收端的RTP端口,或者让发送端回复它要发往的端口,但这种方式会破坏NAT通道的自动建立,需要额外做UDP打洞(比如接收端先往发送端的RTP端口发一个空包),反而更复杂。
2. 发送"startrtp"后能否从UDPClient获取PeerIP和PeerPort?
接收端的TIdUDPClient如果没有绑定固定端口,系统会分配临时端口,你可以通过IdUDPClient1.Socket.Binding.Port获取这个临时端口,但这个端口不能被RTP接收器(另一个TIdUDPServer)复用——因为同一个端口不能被两个Indy组件同时绑定,所以这个方案不可行。
关于UDP双向通信的组件控制权移交(无缝切换)
UDP本身无连接,但Indy的组件是基于端口绑定的,要实现"无缝移交",核心是让所有双向UDP交互都通过同一组端口对:
- 接收端不要同时用
TIdUDPClient和TIdUDPServer,改用单个TIdUDPServer:- 用
SendTo方法发送"startrtp"命令到发送端的命令服务器端口 - 同时监听这个
TIdUDPServer绑定的端口,接收发送端发来的RTP数据
- 用
- 发送端这边,命令服务器收到"startrtp"后,直接把RTP发送器的
PeerIP和PeerPort设为收到命令的那个IP和端口,启动发送即可。
这样所有的UDP包都走同一个端口对,路由器NAT会自动维护双向通道,不需要额外的配置,也不存在组件控制权移交的问题——因为从始至终只用一个UDP组件处理接收端的所有UDP交互。
内容的提问来源于stack exchange,提问作者Ross
相关产品推荐
相关产品推荐

