簡體   English   中英

C++ UDP 從客戶端接收到第一個數據包后,套接字無法從服務器發送回客戶端

[英]C++ UDP Socket not working to send back from server to client after receiving first packets from client

在 C++ 中編寫 UDP 客戶端-服務器應用程序(在過去 15 年中以多種語言完成了很多次),但不知何故,這個應用程序無法正常工作。

我目前無法發布實際代碼或最小的可重現應用程序,但如果有人可以通過屏幕共享幫助快速解決此問題,我願意支付實時幫助。

我認為這是 C++ sockets 的特殊性以及我在這個非常復雜的特定應用程序中使用它們的方式。

基本上問題是客戶端沒有收到從服務器發送到客戶端的數據包,只有當所述客戶端位於單獨的 nat 上時。 當在同一本地網絡中並使用其本地 IP 時,一切都按預期工作。

這是我正在做的事情:

  1. 客戶端sendto(...)數據包通過 UDP 使用特定的服務器主機和端口 12345 發送到服務器(並不停地發送這些)
  2. 在另一個線程上,客戶端在端口 12345 和“0.0.0.0”上bind(...)並嘗試在循環中poll()recvfrom() (當客戶端在單獨的 nat 上時,poll 總是在此處返回 0)
  3. 服務器bind()在端口 12345 和 "0.0.0.0" 然后poll()recvfrom()循環
  4. 在從客戶端接收到第一條 UDP 消息后,它啟動一個線程,用於在新套接字上將 UDP 消息發送回客戶端,使用從recvfrom()獲得的 sockaddr_in 傳遞sendto()命令。

結果:服務器完美地接收到來自所有客戶端的所有消息,並將所有消息發送回所有客戶端,但任何不在同一個 NAT 上的客戶端將永遠不會收到任何消息( poll()始終返回 0)。

據我了解,當客戶端在特定遠程端口(在本例中為 12345)上向服務器發送 UDP 消息時,它將在其 NAT 上打一個洞,以便它可以從該遠程服務器接收消息港口...

我測試了五種不同的客戶端網絡配置:

  1. 與服務器的本地網絡,使用本地 IP 地址(WORKS)
  2. 客戶端使用 VPN 時與服務器的本地網絡,因此通過遠程 NAT(不起作用)
  3. 與服務器的本地網絡,但客戶端使用 WAN ip 地址連接到服務器(不起作用)
  4. 來自朋友連接的實際遠程網絡中的客戶端,在路由器后面(不起作用)
  5. 客戶端通過使用我的手機創建的 wifi 熱點(不工作)

對於上述所有測試,服務器正確接收來自客戶端的所有通信。

我還嘗試將sendto()的端口強制為 12345,而不是使用從recvfrom()設置的 sockaddr_in ,同樣的問題。

我做錯什么了嗎?

如果您想提供幫助但需要查看實際代碼,我可以通過屏幕共享實時完成,我會為幫助付費。

謝謝。

此外,如果有人可以將我指向一個很棒的網站,我可以在那里支付非常快速的幫助,請告訴我,我什至不費心搜索谷歌,因為我真的想要嘗試這些服務的人的實際建議,而不是廣告試圖扯我...

只允許原始接收方套接字回復客戶端,因為在 NAT 中打開端口的是客戶端請求。 所以要么使用服務器中的同一個socket進行接收和回復,要么獲取第二個服務器socket綁定的端口,並通過原始服務器端口傳遞一個初始消息,以便A可以發送給它並打孔.

當套接字是全雙工通信 object 時,創建兩個半雙工 sockets 看起來很奇怪,我使用第一個選項 go。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM