Вот изучаю здесь код: http://cs.ecs.baylor.edu/~donahoo/practical/JavaSockets2/code/UDPEchoServerSelector.java
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.DatagramChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.util.Iterator;
public class UDPEchoServerSelector {
private static final int TIMEOUT = 3000; // Wait timeout (milliseconds)
private static final int ECHOMAX = 255; // Maximum size of echo datagram
public static void main(String[] args) throws IOException {
if (args.length != 1) // Test for correct argument list
throw new IllegalArgumentException("Parameter(s): <Port>");
int servPort = Integer.parseInt(args[0]);
// Create a selector to multiplex client connections.
Selector selector = Selector.open();
DatagramChannel channel = DatagramChannel.open();
channel.configureBlocking(false);
channel.socket().bind(new InetSocketAddress(servPort));
channel.register(selector, SelectionKey.OP_READ, new ClientRecord());
while (true) { // Run forever, receiving and echoing datagrams
// Wait for task or until timeout expires
if (selector.select(TIMEOUT) == 0) {
System.out.print(".");
continue;
}
// Get iterator on set of keys with I/O to process
Iterator<SelectionKey> keyIter = selector.selectedKeys().iterator();
while (keyIter.hasNext()) {
SelectionKey key = keyIter.next(); // Key is bit mask
// Client socket channel has pending data?
if (key.isReadable())
handleRead(key);
// Client socket channel is available for writing and
// key is valid (i.e., channel not closed).
if (key.isValid() && key.isWritable())
handleWrite(key);
keyIter.remove();
}
}
}
public static void handleRead(SelectionKey key) throws IOException {
DatagramChannel channel = (DatagramChannel) key.channel();
ClientRecord clntRec = (ClientRecord) key.attachment();
clntRec.buffer.clear(); // Prepare buffer for receiving
clntRec.clientAddress = channel.receive(clntRec.buffer);
if (clntRec.clientAddress != null) { // Did we receive something?
// Register write with the selector
key.interestOps(SelectionKey.OP_WRITE);
}
}
public static void handleWrite(SelectionKey key) throws IOException {
DatagramChannel channel = (DatagramChannel) key.channel();
ClientRecord clntRec = (ClientRecord) key.attachment();
clntRec.buffer.flip(); // Prepare buffer for sending
int bytesSent = channel.send(clntRec.buffer, clntRec.clientAddress);
if (bytesSent != 0) { // Buffer completely written?
// No longer interested in writes
key.interestOps(SelectionKey.OP_READ);
}
}
static class ClientRecord {
public SocketAddress clientAddress;
public ByteBuffer buffer = ByteBuffer.allocate(ECHOMAX);
}
}
И не понимаю, каким образом можно узнать через DatagramChannel длинну приходящего пакета чтобы из ByteBuffer считать нужное количество?
Прежде всего важно понять, что попадание канала в выборку селектора по готовности на чтение не означает, что пришли все данные. Пришло сколько-то данных. Отправляющий код мог передать 512 байт, а селектор может выбрать канал 42 раза - несколько раз по одному байту, несколько раз по нескольку десятков байт и т.д. Поэтому в цикле мультиплексирования нельзя ожидать поступления всех данных, а надо только читать и добавлять в буффер столько, сколько пришло, до тех пор, пока не накопится нужное количество. В тех случаях, когда обмен идёт по tcp и через одно соединение будет передан только один блок данных, проще всего определить об окончании передачи по тому, что метод read
вернул -1. Если же через один канал передаётся множество блоков или используется udp, то принимающая сторона должна знать, сколько она должна принять. Самый простой, но весьма неудобный способ - это передавать блоки данных фиксированного размера. Другой - это сначала передать int
или long
, содержащий размер передаваемых данных, а потом передать столько данных.
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Никак не могу понять, что должен возвращать return, true или false, или же вообще какое-то значение?
Находил такую реализацию распознавания текста (используя гугл сервисы) архив с исходникомТам открывается подобное окно
Необходимо сделать несколько уровней игрыНужно ли каждый уровень записывать в отдельный класс? Как сделать так чтобы на каждом уровне был...
в DAO пытаюсь выполнить такой запрос: UPDATE PRODUCTS SET PRICE = ?, SET STOCK = ? WHERE SOURCE_ID = ? используя PreparedStatement(), но получаю javasql