许多人打电话给服务器

时间:2017-01-08 01:21:39

标签: java sockets udp

我使用Selector和频道(ServerSocketChannelDatagramChannel)在同一套接字中创建udp / tcp heandler。当我将DatagramPacket的数据包发送到服务器时,服务器会注册许多选择器(2-8,每次都不同),每次服务器都会处理这些密钥。因此,此查询在使用trim()后会显示空字段,但其中一个键具有查询文本。

服务器

public class Server extends Thread {
public void run() {
    SocketAddress port = new InetSocketAddress(ReaderProperty.getPropertyPort());
    try {
        Selector selector = Selector.open();

        ServerSocketChannel tcpServer = ServerSocketChannel.open();
        tcpServer.socket().bind(port);
        tcpServer.configureBlocking(false);
        tcpServer.register(selector, SelectionKey.OP_ACCEPT);

        DatagramChannel udpServer = DatagramChannel.open();
        udpServer.socket().bind(port);
        udpServer.configureBlocking(false);
        udpServer.register(selector, SelectionKey.OP_READ);

        while(true) {
            try {
                selector.select();

                Set<SelectionKey> keys = selector.selectedKeys();

                for (Iterator<SelectionKey> i = keys.iterator(); i.hasNext();) {
                    SelectionKey key = i.next();
                    i.remove();

                    Channel c = key.channel();

                    if (key.isAcceptable() && c == tcpServer) {
                        new TCPResponse(tcpServer.accept().socket()).start();
                    } else if (key.isReadable() && c == udpServer) {
                        new UDPResponse(udpServer, key.channel()).start();
                    }
                }

                keys.clear();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

UDPRequest

public class UDPRequest {
public UDPRequest(String server, int port, String query) {
    DatagramSocket client = null;
    try {
        client = new DatagramSocket();

        byte[] sendByte = query.getBytes();
        byte[] receiveByte = new byte[32];

        DatagramPacket sender = new DatagramPacket(sendByte, sendByte.length, InetAddress.getByName(server), port);
        client.send(sender);

        DatagramPacket receiver = new DatagramPacket(receiveByte, receiveByte.length);
        client.receive(receiver);

        ByteBuffer buf = ByteBuffer.allocate(32);
        buf.clear();
        buf = ByteBuffer.wrap(receiver.getData());

        String receiveLine = new String(buf.array(), Charset.forName("UTF-8")).trim();

        System.out.println("IP address or DOMAIN NAME: " + receiveLine);

        if (receiveLine.equals("true")) {
            new TCPRequest(server, port, query);
        }
    } catch(Exception e) {
        e.getStackTrace();
    }
    if (client != null) {
        client.close();
    }
}

UDPResponse

public class UDPResponse extends Thread {
private DatagramChannel channel = null;
private SelectableChannel selectableChannel = null;

public UDPResponse(DatagramChannel channel, SelectableChannel selectableChannel) {
    super("UDPResonse");
    this.channel = channel;
    this.selectableChannel = selectableChannel;
}

@Override
public void run() {
    try {
        ByteBuffer buf = ByteBuffer.allocate(32);
        buf.clear();
        InetSocketAddress address = (InetSocketAddress) ((DatagramChannel) selectableChannel).receive(buf);

        String inputLine = new String(buf.array(), Charset.forName("UTF-8"));
        String outputLine = Utils.processCommand(inputLine.trim());

        buf.clear();
        try {
            buf.put(outputLine.getBytes());
        } catch (BufferOverflowException overflow) {
            buf.put("true".getBytes());
        }
        buf.flip();

        try {
            channel.send(buf, address);
        } catch (NullPointerException ignored) {
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

为什么我向服务器发出一个查询,但服务器一次获得2-8个连接?

UPD: 只有在忽略这些空请求时才找到解决方案:

if (inputLine.trim().length() != 0) {
    //process...
}

0 个答案:

没有答案