服务器(或客户端)未回答所有请求

时间:2019-07-06 10:39:47

标签: java server nio

嗯,所以我对服务器进行了编程,它将同时具有许多连接。我遇到了一个问题,那就是它并不能解决所有问题。 我不确定服务器是否有问题,如果需要,我还可以提供客户端。

我不知道该怎么做

public abstract class ConnectionHost {

    private final ConnectionCreator connectionCreator;
    private ServerSocketChannel serverSocketChannel;    
    private Boolean running;
    private Integer port;

    /**
     * @param connectionCreator
     * @param port
     */
    public ConnectionHost(ConnectionCreator connectionCreator, Integer port) {
        this(connectionCreator);
        this.port=port;
        try {
            this.open(port);
        } catch (Exception exception) {
            throw new BloumException("Unable to open server. -> "+exception.getMessage());
        }
    }

    /**
     * @param connectionCreator
     */
    public ConnectionHost(ConnectionCreator connectionCreator) {
        this.connectionCreator=connectionCreator;
        this.running=false;
    }

    /**
     * Opens a connection host.
     * @param port
     * @throws Exception
     */
    public void open(Integer port) throws Exception{
        if(this.isRunning())throw new ConnectionAlredyRunningException();
        this.port=port;
        this.running=true;
        final HashMap<SocketChannel, ByteBuilder> sessions = new HashMap<>();

        try(final Selector selector = Selector.open(); final ServerSocketChannel serverSocketChannel = ServerSocketChannel.open()){
            this.serverSocketChannel=serverSocketChannel;
            this.prepareChannel(serverSocketChannel, selector);
            while(this.isRunning()){
                //if(!serverSocketChannel.isOpen())serverSocketChannel.bind(new InetSocketAddress(this.getPort()));
                try{
                    if(selector.isOpen()){
                        final Integer numKeys = selector.select();
                        if(numKeys>0){
                            this.handleKeys(serverSocketChannel, selector.selectedKeys(), sessions);
                        }
                    }else{
                        this.close();
                    }
                }catch(Exception exception){throw new BloumExceptionAdapter(exception);}
            }
        }finally{
            sessions.clear();
        }
    }

    /**
     * @param serverSocketChannel
     */
    private void prepareChannel(ServerSocketChannel serverSocketChannel, Selector selector) throws Exception{
        serverSocketChannel.socket().setReuseAddress(true);
        serverSocketChannel.configureBlocking(false);
        serverSocketChannel.bind(new InetSocketAddress(this.getPort()));
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
    }

    public abstract Boolean handle(Connection connection, byte[] data);

    private void handleKeys(final ServerSocketChannel serverSocketChannel, Set<SelectionKey> keys, HashMap<SocketChannel, ByteBuilder> sessions) throws Exception{
        final Iterator<SelectionKey> iterator = keys.iterator();
        while(iterator.hasNext()){
            final SelectionKey selectionKey = iterator.next();
            iterator.remove();
            if(selectionKey.isValid()){
                if(selectionKey.isAcceptable()){
                    final ServerSocketChannel serverSocketChannel2 = (ServerSocketChannel)selectionKey.channel();
                    final SocketChannel socketChannel = serverSocketChannel2.accept();
                    socketChannel.configureBlocking(false);
                    socketChannel.register(selectionKey.selector(), SelectionKey.OP_READ);
                    sessions.put(socketChannel, new ByteBuilder());

                }else if(selectionKey.isReadable()){
                    final SocketChannel socketChannel = (SocketChannel)selectionKey.channel();
                    final ByteBuffer byteBuffer = ByteBuffer.allocate(Connection.MAX_BUFFER_SIZE);

                    final Integer bytesRead = socketChannel.read(byteBuffer);
                    if(bytesRead!=-1){
                        byte[] data = new byte[bytesRead];
                        System.arraycopy(byteBuffer.array(), 0, data, 0, bytesRead);
                        Boolean autoClose = true;
                        if(ConnectionHost.this.handle(this.getConnectionCreator().createConnection(socketChannel), data)){
                            autoClose=true;
                        }else autoClose=false;


                        if(autoClose){
                            sessions.remove(socketChannel);
                            socketChannel.close();
                        }else{
                            if(!sessions.containsKey(socketChannel))sessions.put(socketChannel, new ByteBuilder());
                        }
                    }
                }else throw new BloumException("The given key is not supported.");
            }else throw new BloumException("The key is not valid anymore.");

        }
    }

    /**
     * Shuts the server down.
     */
    public void close(){
        if(!this.isRunning())throw new ConnectionNotRunningException();
        this.running=false;
        try {
            this.serverSocketChannel.close();
        } catch (IOException exception) {
            throw new BloumException(exception.getMessage());
        }
    }

    /**
     * @return the port
     */
    public Integer getPort() {
        return port;
    }

    /**
     * @param port the port to set
     */
    public void setPort(Integer port) {
        this.port = port;
    }

    /**
     * @return the connectionCreator
     */
    public ConnectionCreator getConnectionCreator() {
        return connectionCreator;
    }

    /**
     * @return the running
     */
    public Boolean isRunning() {
        return running;
    }

}

没有错误消息。

0 个答案:

没有答案