C # UDP Сервер / Клиент - NAT - PullRequest
1 голос
/ 22 февраля 2012

Я пытаюсь отправить сообщение (через UDP) с моего клиента на мой сервер. Сервер должен ответить на это сообщение, и если клиент получит этот ответ, он должен распечатать сообщение.

Если я запускаю клиент и сервер в моей локальной сети, все работает нормально. Если я пытаюсь подключиться через Интернет с другого компьютера за пределами моей сети, сервер получает запрос клиента, отправляет ответ обратно, но клиент никогда не получает этот ответ. Клиент и сервер оба находятся за NAT, но я перенаправил порты на NAT сервера, и сервер получил свой собственный DNS. Я уже пробовал NAT traversal, но он дает мне тот же IP и адрес порта, что и IPEndPoint сервера, после получения запроса клиента.

Я понятия не имею, как это исправить, поэтому любые рекомендации будут высоко оценены.

Клиент

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

 }

Ответы [ 2 ]

0 голосов
/ 09 августа 2013

Вам не нужно делать ничего необычного для прохождения NAT в описанной вами настройке, вам просто нужно отправить его с сервера обратно вашему клиенту; в частности: вы должны отправить обратно в конечную точку, то есть IP и порт, вы получили его на.

client.Send(data, data.Length, remoteEndPoint); // remoteEndPoint is the IPEndPoint you got the datagram on
0 голосов
/ 22 февраля 2012

Я полагаю, что это проблема настройки порта,

8080, скорее всего, будет настроен как альтернативный http

"UdpClient, который вы используете для получения дейтаграмм, должен быть создан с использованиемномер многоадресного порта " от MSDN

Надеюсь, это поможет и удачи

Кришна

...