На объекте вы можете достичь этого с помощью setattr
>>> class A(object): pass
>>> a=A()
>>> setattr(a, "hello1", 5)
>>> a.hello1
5
Конструкция для этого в определенной степени зависит от того, требуется ли для каждого полного «диалога» 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);
}
}
Поскольку 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() );
}
}
}
Вы смотрели проект Apache Mina ? Я полагаю, что даже один из его примеров поможет вам настроить сервер на основе UDP. Если бы это было для реального продукта, я бы не рекомендовал пытаться придумать собственную реализацию с нуля. Для этого вам понадобится библиотека, поэтому вы не используете один поток на соединение, а скорее пул потоков.
Я действительно не вижу в этом необходимости.
Это правильно для школы?
Если вам нужно отслеживать клиентов, у вас должно быть местное представительство каждого клиента. (объект Client на вашем сервере). Он может позаботиться о любых клиентских действиях, которые вам нужно сделать.
В этом случае вам необходимо выяснить, с какого клиента было отправлено сообщение. (используя информацию из сообщения.) Вы можете хранить клиентов на карте.
Наиболее эффективный способ, вероятно, состоит в том, чтобы выполнять всю обработку в главном потоке, если все, что нужно сделать, не может «заблокировать» ожидание внешних событий. (или если что-то, что должно произойти, может занять много времени, а некоторые очень короткое.)
public class Client {
public void handleMessage(Message m) {
// do stuff here.
}
}
Клиентский объект может начать новый поток в handleMessage (), если это необходимо.
Вы не должны