简体   繁体   English

udp数据包未通过

[英]udp packet not coming through

I have the following setup: 我有以下设置:

Dedicated server --> Internet --> Modem (telenet) --> Router --> client 专用服务器-> Internet->调制解调器(telenet)->路由器->客户端

  1. The client initiates a tcp connection with the server to register itself on the server, and gives through following info: 客户端启动与服务器的tcp连接以在服务器上注册自己,并提供以下信息:
    • mac address of the client 客户端的mac地址
    • external ip; 外部ip; this is retrieved by using webclient string download from whatsmyip.org 这是通过使用从whatsmyip.org下载的webclient字符串来检索的
  2. Some updates occur on the server and of course the client needs to be notified, so the client can start a sync session on its own: 服务器上会发生一些更新,并且当然需要通知客户端,因此客户端可以自己启动同步会话:
    • To notify the client, the server sends a udp packet from the server to the modem (to the external ip, earlier received from the client) , in the meanwhile the client is listening for udp packets behind the router. 为了通知客户端,服务器将udp数据包从服务器发送到调制解调器(发送到外部IP,较早从客户端接收到) ,同时客户端正在侦听路由器后面的udp数据包。

The problem is that I'm not receiving any packets.. Is my scenario possible, what should I do? 问题是我没有收到任何数据包。我的情况是否可行,我该怎么办?

Requirements: 要求:

  • Solving this by enabling port-forwarding on the router isn't an option 不能通过在路由器上启用端口转发来解决此问题
  • The server has a fixed ip 服务器有固定的IP
  • The client can be disconnected from the internet, at times 有时可以断开客户端与互联网的连接
  • The solution has to work on different kinds of routers 该解决方案必须适用于不同类型的路由器
  • Both ports at which packets are send & received are the same 发送和接收数据包的两个端口都相同
  • All programming is done in C# 所有编程均在C#中完成
  • The server notifies the client when there is an update, the client may never poll the server for updates to prevent overload (in case several clients are doing this the same time) 当有更新时,服务器会通知客户端,客户端可能永远不会轮询服务器以获取更新以防止过载(以防多个客户端同时执行此操作)

Greets Daan & thanks in advance 问候大安,并提前致谢

EDIT: 编辑:
Code example from server: 来自服务器的代码示例:

UdpClient udpSender = new UdpClient();
IPEndPoint localServerGateway = new IPEndPoint(IPAddress.Parse(externalIp), 8003);
string message = "testmessage";
byte[] messageBytes = Encoding.ASCII.GetBytes(message);
try
{
     udpSender.Send(messageBytes, messageBytes.Length, localServerGateway);
}
catch (Exception error)
{
     Console.WriteLine("Error while sending message: " + error.ToString());
}
udpSender.Close();

Code example from client: 客户端代码示例:

private void listenForMasterSyncRequest()
{
        bool done = false;
        IPEndPoint groupEP = new IPEndPoint(IPAddress.Any, 8003);

        try
        {
            while (!done)
            {
                byte[] bytes = masterSyncUdpListener.Receive(ref groupEP);
                handleMessage(bytes, bytes.Length, true); // handles incoming messages, this is never reached because no packets are received :-(
            }

        }
        catch (Exception e)
        {
            Console.WriteLine("An error occured while listening to server broadcast updates: " + e.ToString());
        }
        finally
        {
            masterSyncUdpListener.Close();
        }
    }

NAT works by setting up sessions between external and internal hosts. NAT通过在外部主机和内部主机之间建立会话来工作。 But the session must be initiated on the internal side, and in your case that's the client side. 但是会话必须在内部启动,在您的情况下,这是客户端。 So the way it has to work is that the client has to poll the server, sending a UDP packet to a particular port on the server asking if a sync is needed. 因此,它的工作方式是客户端必须轮询服务器,将UDP数据包发送到服务器上的特定端口,询问是否需要同步。 The server must send a UDP response from that same port back to the same port the client sent the original request. 服务器必须将UDP响应从同一端口发送回客户端发送原始请求的同一端口。 If you do it this way packets from the server will get through, otherwise they will not. 如果以这种方式执行此操作,则来自服务器的数据包将通过,否则将无法通过。 I know this works because this is exactly how DNS lookups work from behind NAT. 我知道这可行,因为这正是从NAT后面进行DNS查找的方式。

由于您无法控制路径中的NAT设备,因此这里唯一明智的方法是使用TCP作为主要传输方式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM