Сокеты Java датаграмм не получают пакеты - PullRequest
1 голос
/ 03 декабря 2010

Я пытаюсь использовать дейтаграммы Java для создания потока пакетов между сервером и клиентом.Проблема в том, что, хотя я получаю подтверждение того, что пакеты отправляются, они все теряются до того, как достигнут клиентского прослушивателя, который я настроил.У меня есть это сейчас, так что через 5 секунд есть тайм-аут, который происходит каждый раз, когда я запускаю его.

class DGServer extends Thread
{
    private DatagramSocket server;

    public DGServer() throws IOException
    {
        server = new DatagramSocket();
    }

    public void run()
    {
        try
        {
            server.connect(App.Local, 4200);
            System.out.println("Server starting...");

            int i = 0;

            while (server.isConnected() && (i < 256))
            {
                byte[] buffer = new byte[1];
                buffer[0] = (byte) ++i;
                DatagramPacket packet = new DatagramPacket(buffer, buffer.length, App.Local, 4200);
                System.out.println("Sedning " + i + " to client...");

                server.send(packet);

                Thread.sleep(500);
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        System.out.println("Server Finished!");

        if (! server.isClosed())
            server.close();
    }

}

class DGClient extends Thread
{
    private DatagramSocket client;

    public DGClient() throws SocketException
    {
        client = new DatagramSocket();
    }

    public void run()
    {
        try
        {
            client.connect(App.Local, 4200);
            client.setSoTimeout(5000);
            System.out.println("Client starting...");

            int i = 0;

            while (client.isConnected() && (i < 256))
            {
                byte[] buffer = new byte[1];
                DatagramPacket packet;
                packet = new DatagramPacket(buffer, 1, App.Local, 4200);
                //System.out.println("Sedning " + i + " to server...");

                client.receive(packet);

                buffer = packet.getData();          
                System.out.println("Client Received:\t" + packet.getData()[0]);

                Thread.sleep(500);
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        System.out.println("Client Finished!");

        if (! client.isClosed())
            client.close();
    }

}

Вы можете выбрать просмотр второго класса.Они во многом одинаковы, он просто заменяет server.send на client.receive.Кроме того, этот класс не был разработан, чтобы действительно делать что-то важное.Итак, большая часть кода (например, обработка исключений) написана очень упрощенно.

Могу ли я что-нибудь сделать, чтобы предотвратить потерю пакетов?У меня есть порт, перенаправленный на мой компьютер (не то, чтобы он имел значение, я использую свой локальный хост, который, если вам интересно, App.Local).

Также, дополнительный вопрос.Первоначально я настроил его как один класс, закодировал для отправки пакета, затем развернулся и получил один.Но это вызвало исключение, потому что «ICMP-порт недоступен».Кто-нибудь знает, почему это происходит?

Ответы [ 6 ]

5 голосов
/ 03 декабря 2010

Хорошо, во-первых, я думаю, что вы тестируете и сервер, и клиент одновременно, поэтому вы не знаете, какой из них выходит из строя.

Вы должны использовать netcat (nc) или wireshark для проверки клиента

с помощью netcat вы можете запустить следующую команду

nc -l -u -p 4200 -vv

Это скажет netcat прослушивать (-l) по udp (-u) через порт (-p 4200) и быть очень многословным (-vv)

Таким образом, вы сможете проверить, может ли ваш клиент подключиться к чему-либо.

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

nc -u [target ip] 4200

Здесь есть шпаргалка netcat

Вы также можете проверить netcat на netcat, чтобы определить, является ли это чисто сетевой проблемой. Возможно, брандмауэры / NAT настроены неправильно

1 голос
/ 09 мая 2012

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

1 голос
/ 03 декабря 2010

Вы не привязываете отправляющий сокет к определенному номеру порта, поэтому клиент не сможет отправить его, если он подключен.Я подозреваю, что у вас та же проблема и в обратном направлении, то есть клиентский сокет не привязан к порту 4200. Это объясняет все.

Я бы избавился от соединений и использовал явные номера портов при отправке и номер входящего порта при ответе.

1 голос
/ 03 декабря 2010

Мне кажется, что какой-то фильтр пакетов / межсетевой экран мешает UDP-трафику между клиентом и сервером на используемом вами порту.Это может быть простая фильтрация пакетов, это может быть NAT (который мешает UDP-трафику, если вы не предпримете особые шаги), это может быть случайная неправильная конфигурация сети.

Но это вызвало исключение, потому что 'ICMPПорт недоступен ».Кто-нибудь знает, почему это происходит?

IMO, это еще одно доказательство фильтрации пакетов.

(Тем не менее, также немного неожиданно, что вы должны получить это в ответ на попытку отправки дейтаграммы. Я бы просто ожидал, что вообще не будет никакого ответа, и любые ответы ICMP на запрос UDP длябыли сброшены операционной системой на пол. Но, я могу ошибаться по этому поводу ...

Теперь, если вы использовали обычный потоковый сокет, например, TCP / IP, это поведение было бы понятно.)

1 голос
/ 03 декабря 2010

Почему сервер и клиент подключаются?Разве одна сторона не должна отправлять данные?

Что-то вроде:


DatagramSocket socket = new DatagramSocket();

DatagramPacket packet = new DatagramPacket(buf, buf.length, 
                                           address, 4200);
socket.send(packet);

0 голосов
/ 03 декабря 2010

Я уверен, что вы знаете, что UDP - это протокол с потерями, и вы разрешили это. Тем не менее, вы должны ожидать получить несколько пакетов.

Я предлагаю вам проверить, работает ли ваша программа, используя клиент и сервер на одном и том же хосте и на разных хостах, избегая любых брандмауэров. Если это работает, значит, у вас проблема с конфигурацией сети.

...