Как я могу реализовать многопоточный сервер на основе UDP в Java?

На объекте вы можете достичь этого с помощью setattr

>>> class A(object): pass
>>> a=A()
>>> setattr(a, "hello1", 5)
>>> a.hello1
5
10
задан 21 April 2009 в 15:19
поделиться

4 ответа

Конструкция для этого в определенной степени зависит от того, требуется ли для каждого полного «диалога» UDP просто один запрос и немедленный ответ, будь то один запрос или ответ с повторными передачами, или будет необходимость обрабатывать много пакетов для каждого клиента.

Сервер RADIUS, который я написал, имел модель «один запрос + повторная передача» и порождался поток для каждого входящего пакета.

Когда каждый DatagramPacket был получен, он был передан новому потоку, и затем этот поток отвечал за отправку ответа обратно. Это было связано с тем, что вычисления и доступ к базе данных, связанные с генерацией каждого ответа, могли занимать относительно много времени, и это ' Проще создать поток, чем иметь какой-то другой механизм для обработки новых пакетов, которые приходят, пока старые пакеты еще обрабатываются.

public class Server implements Runnable {
    public void run() {
        while (true) {
            DatagramPacket packet = socket.receive();
            new Thread(new Responder(socket, packet)).start();
        }
    }
}

public class Responder implements Runnable {

    Socket socket = null;
    DatagramPacket packet = null;

    public Responder(Socket socket, DatagramPacket packet) {
        this.socket = socket;
        this.packet = packet;
    }

    public void run() {
        byte[] data = makeResponse(); // code not shown
        DatagramPacket response = new DatagramPacket(data, data.length,
            packet.getAddress(), packet.getPort());
        socket.send(response);
    }
}
15
ответ дан 3 December 2019 в 16:30
поделиться

Поскольку UDP является протоколом без установления соединения, зачем вам нужно создавать новый поток для каждого соединения? Когда вы получаете пакет UDP, возможно, вам следует создать новый поток, чтобы позаботиться о работе с полученным сообщением.

Соединения UDP не похожи на соединения TCP. Они не остаются активными, и такова конструкция UDP.

Метод handlePacket () этого следующего блока кода может делать с полученными данными все, что захочет. И многие клиенты могут отправлять несколько пакетов одному и тому же слушателю UDP. Возможно, это поможет вам.

public void run() {
        DatagramSocket wSocket = null;
        DatagramPacket wPacket = null;
        byte[] wBuffer = null;

        try {
            wSocket = new DatagramSocket( listenPort );
            wBuffer = new byte[ 2048 ];
            wPacket = new DatagramPacket( wBuffer, wBuffer.length );
        } catch ( SocketException e ) {
            log.fatal( "Could not open the socket: \n" + e.getMessage() );
            System.exit( 1 );
        }

        while ( isRunning ) {
            try {
                wSocket.receive( wPacket );
                handlePacket( wPacket, wBuffer );
            } catch ( Exception e ) {
                log.error( e.getMessage() );
            }
        }
    }
6
ответ дан 3 December 2019 в 16:30
поделиться

Вы смотрели проект Apache Mina ? Я полагаю, что даже один из его примеров поможет вам настроить сервер на основе UDP. Если бы это было для реального продукта, я бы не рекомендовал пытаться придумать собственную реализацию с нуля. Для этого вам понадобится библиотека, поэтому вы не используете один поток на соединение, а скорее пул потоков.

3
ответ дан 3 December 2019 в 16:30
поделиться

Я действительно не вижу в этом необходимости.

Это правильно для школы?

Если вам нужно отслеживать клиентов, у вас должно быть местное представительство каждого клиента. (объект Client на вашем сервере). Он может позаботиться о любых клиентских действиях, которые вам нужно сделать.

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

Наиболее эффективный способ, вероятно, состоит в том, чтобы выполнять всю обработку в главном потоке, если все, что нужно сделать, не может «заблокировать» ожидание внешних событий. (или если что-то, что должно произойти, может занять много времени, а некоторые очень короткое.)

public class Client {

    public void handleMessage(Message m) {
    // do stuff here.
    }

}

Клиентский объект может начать новый поток в handleMessage (), если это необходимо.

Вы не должны

1
ответ дан 3 December 2019 в 16:30
поделиться
Другие вопросы по тегам:

Похожие вопросы: