嗯,所以我对服务器进行了编程,它将同时具有许多连接。我遇到了一个问题,那就是它并不能解决所有问题。 我不确定服务器是否有问题,如果需要,我还可以提供客户端。
我不知道该怎么做
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;
}
}
没有错误消息。