C#UDP服务器/客户端-NAT

C#UDP服务器/客户端-NAT,c#,udp,client-server,nat-traversal,C#,Udp,Client Server,Nat Traversal,我正在尝试将一条消息(通过UDP)从我的客户端发送到我的服务器。服务器应回答此消息,如果客户端收到此回答,则应打印一条消息 如果我在本地网络上运行客户端和服务器,一切正常。 如果我试图从网络之外的另一台PC通过internet进行连接,服务器会收到客户机的请求,并发送回复,但客户机从未收到此回复。客户端和服务器都在NAT后面,但我在服务器的NAT上转发了端口,服务器得到了自己的DNS。我已经尝试过NAT遍历,但它在接收到客户机的请求后,为我提供了与服务器的IPEndPoint相同的IP和端口地址

我正在尝试将一条消息(通过UDP)从我的客户端发送到我的服务器。服务器应回答此消息,如果客户端收到此回答,则应打印一条消息

如果我在本地网络上运行客户端和服务器,一切正常。 如果我试图从网络之外的另一台PC通过internet进行连接,服务器会收到客户机的请求,并发送回复,但客户机从未收到此回复。客户端和服务器都在NAT后面,但我在服务器的NAT上转发了端口,服务器得到了自己的DNS。我已经尝试过NAT遍历,但它在接收到客户机的请求后,为我提供了与服务器的IPEndPoint相同的IP和端口地址

我不知道如何解决这个问题,所以如果有任何指导,我将不胜感激

客户

public static void Main()
{
    Thread receiveThread = new Thread(new ThreadStart(ReceiveData));
    receiveThread.Start();

    object[] oData = {1};
    sendData(oData, 0,0, "Li"); 

    while (true)
    {
        Console.ReadLine();
    }
}


private void receiveData()
{
    string receivePort = 8080;

    Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
    client.ReceiveTimeout = 1000;
    IPEndPoint end = new IPEndPoint(IPAddress.Any, receivePort);
    client.Bind(end);


    while (true)
    {
        try
        {
            byte[] data = new byte[1024];

            client.Receive(data, 0, data.Length, SocketFlags.None);

            object[] receivedObj = Deserialize(data);

            string sType = (string)receivedObj[3];

            if (sType == "Li")
            {
           console.WriteLine("received Li");
            }
         }
         catch (Exception err)
         {
                Console.WriteLine(err.ToString());
         }
     }
}

public static void sendData(object[] oData, int iFrom, int iTo, string sType)
{
    string sendPort = 17171;

    UdpClient client = new UdpClient();

    string IP = "ThisIsTheDNSofmyServer.com"; //ServerDNS
    //string IP = "192.168.xxx.xxx"; //serverIP in LAN 

    if (IP.StartsWith("T")) 
    {
        IP = (Dns.GetHostAddresses(IP))[0].ToString();
    }

    IPEndPoint remoteEndPoint = new IPEndPoint(IPAddress.Parse(IP), sendPort);

    oData[1] = iFrom;
    oData[2] = iTo;
    oData[3] = sType;

    Byte[] data = Serialize(oData);
    client.Send(data, data.Length, remoteEndPoint);

}
服务器的代码几乎相同:

public static void Main()
{
    Thread receiveThread = new Thread(new ThreadStart(ReceiveData));
    receiveThread.Start();

    while (true)
    {
        Console.ReadLine();
    }
}

private static void ReceiveData()
{
    int receivePort = 17171;
    UdpClient client = new UdpClient(receivePort);

    while (true)
    {
        try
        {
            IPEndPoint anyIP = new IPEndPoint(IPAddress.Any, 0);
            byte[] data = new byte[1024];

            data = client.Receive(ref anyIP);

            object[] receivedObj = Deserialize(data);

            //if I receive data send an Answer
            sendData(receivedObj, 0,0,"Li",anyIP.Address.ToString()); 

        }
        catch (Exception err)
        {
            Console.WriteLine(err.ToString());
        }
    }
}

private static void sendData(object[] oData, int iFrom, int iTo, string sType, string IP)
{
    int sendPort = 8080;
    object[] paket = { oData, iFrom, iTo, sType };

    UdpClient client = new UdpClient();

    IPEndPoint remoteEndPoint = new IPEndPoint(IPAddress.Parse(IP), sendPort); 

    client.Send(data, data.Length, remoteEndPoint);

 }

我相信这是一个港口合作的问题

8080几乎可能被配置为备用http

“用于接收数据报的UdpClient必须使用多播端口号创建”

希望这对你有帮助,祝你好运


Krishna

在您描述的设置中,您不需要做任何不寻常的事情来遍历NAT,您只需要将它从服务器发送回您的客户机;特别是:您必须发送回端点,即IP和端口,您在上收到它

client.Send(data, data.Length, remoteEndPoint); // remoteEndPoint is the IPEndPoint you got the datagram on

不确定,但您可以检查防火墙设置以关闭客户端和服务器上的所有防火墙,以消除潜在问题。如果您的客户机向服务器发送了一条消息,而服务器收到了该消息,那么客户机肯定会收到服务器的回复。除第三方防火墙外,您还可以激活Windows防火墙。尝试为客户端和服务器路由器启用DMZ/端口转发。如果它仍然不起作用,我不太确定它可能是什么。8080可能被任何东西使用-但是如果你成功绑定到它-它就可以使用了。引用中的MSDN不包括上下文“如果您打算接收多播数据报…”。