简体   繁体   English

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

[英]C# UDP Server/Client - NAT

Iam trying to send a message (via UDP) from my client to my server. 我试图从客户端向服务器发送消息(通过UDP)。 The server should answer this message and if the client receives this answer he should print out a message. 服务器应回答此消息,如果客户端收到此回答,则应打印出一条消息。

If i run the client and server on my local network everything works fine. 如果我在本地网络上运行客户端和服务器,则一切正常。 If i try to connect through the internet from another PC outside my network the server receives the request of the client, sends an answer back, but the client never receives this answer. 如果我尝试通过网络之外的另一台PC通过Internet连接,则服务器会收到客户端的请求,将其发送回去,但客户端永远不会收到该答案。 The client and the server are both behind a NAT but i portforwarded the ports at the server´s NAT and the server got its own DNS. 客户端和服务器都位于NAT的后面,但是我将服务器NAT上的端口进行端口转发,服务器获得了自己的DNS。 I already tried NAT traversal but it gives me the same IP and port adress as the IPEndPoint of the server, after receiveing the request of the client, does. 我已经尝试过NAT遍历,但是在收到客户端请求后,它可以为我提供与服务器IPEndPoint相同的IP和端口地址。

I´ve got no idea how to fix this, so any guidance would be much appreciated. 我不知道如何解决此问题,因此任何指导将不胜感激。

Client 客户

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);

}

The server´s code is almost the same: 服务器的代码几乎相同:

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);

 }

You do not need to do anything unordinary to traverse NAT in the setup you described, you just need to send it from the server back to your client; 您无需在描述的设置中进行任何非常规的遍历NAT,只需将其从服务器发送回客户端即可。 specifically: you must send back to the end point, ie IP and port, you received it on. 特别是:您必须发送回终点,即IP 端口。

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

i believe this is a port cofniguration issue, 我认为这是港口配置问题,

8080 is almost likely to be configured as alternate http 8080几乎有可能被配置为备用http

"The UdpClient you use to receive datagrams must be created using the multicast port number" from MSDN 来自MSDN的 “必须使用多播端口号创建用于接收数据报的UdpClient”

Hope this helps and good luck 希望这会有所帮助,并祝你好运

Krishna 克里希纳

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

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