Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JavaNIOSocketchannel仅在关闭输出后发送数据。为什么会这样?_Java_Sockets_Io_Nio_Socketchannel - Fatal编程技术网

JavaNIOSocketchannel仅在关闭输出后发送数据。为什么会这样?

JavaNIOSocketchannel仅在关闭输出后发送数据。为什么会这样?,java,sockets,io,nio,socketchannel,Java,Sockets,Io,Nio,Socketchannel,好的,所以我试图编写一个程序,它接受JavaNIOSocketchannel连接,但也保持它们的开放性。因此,假设客户端发送了一条消息,那么服务器应该立即将相同的消息发送回(简单的Echo服务器),但应答过程不起作用,如果客户端发送新消息,服务器将不会响应,直到我关闭客户端的socketchannel。但在我关闭客户端通道后,所有先前发送的消息都将一次性送达。(对不起,我的英语不好,它不是我的母语) 编写过程用于服务器端和客户端 写作过程: try {

好的,所以我试图编写一个程序,它接受JavaNIOSocketchannel连接,但也保持它们的开放性。因此,假设客户端发送了一条消息,那么服务器应该立即将相同的消息发送回(简单的Echo服务器),但应答过程不起作用,如果客户端发送新消息,服务器将不会响应,直到我关闭客户端的socketchannel。但在我关闭客户端通道后,所有先前发送的消息都将一次性送达。(对不起,我的英语不好,它不是我的母语)

编写过程用于服务器端和客户端

写作过程:

                    try {
                        final ByteBuffer byteBuffer = ByteBuffer.wrap(data);
                        while(byteBuffer.hasRemaining()){
                            socketChannel.write(byteBuffer);
                        }
                        byteBuffer.flip();
                    } catch (IOException exception) {
                        throw new BloumException(exception.getMessage());
                    }
final ByteBuffer byteBuffer = ByteBuffer.allocate(DefaultConnectionCreator.this.getDefaultBufferSize());

                try {
                    while(socketChannel.read(byteBuffer) != -1){    
                        //byteBuffer.clear();
                    }
                } catch (IOException exception) {
                    exception.printStackTrace();
                    throw new BloumException(exception.getMessage());
                }
                return byteBuffer.array();
阅读过程:

                    try {
                        final ByteBuffer byteBuffer = ByteBuffer.wrap(data);
                        while(byteBuffer.hasRemaining()){
                            socketChannel.write(byteBuffer);
                        }
                        byteBuffer.flip();
                    } catch (IOException exception) {
                        throw new BloumException(exception.getMessage());
                    }
final ByteBuffer byteBuffer = ByteBuffer.allocate(DefaultConnectionCreator.this.getDefaultBufferSize());

                try {
                    while(socketChannel.read(byteBuffer) != -1){    
                        //byteBuffer.clear();
                    }
                } catch (IOException exception) {
                    exception.printStackTrace();
                    throw new BloumException(exception.getMessage());
                }
                return byteBuffer.array();
密钥选择过程(自动关闭返回false):

private void handleKeys(最终服务器socketchannel服务器socketchannel、设置键、HashMap会话)引发异常{
final Iterator Iterator=keys.Iterator();
while(iterator.hasNext()){
final SelectionKey SelectionKey=iterator.next();
iterator.remove();
if(selectionKey.isValid()){
如果(selectionKey.isAcceptable()){
final ServerSocketChannel serverSocketChannel2=(ServerSocketChannel)selectionKey.channel();
final-SocketChannel-SocketChannel=serverSocketChannel2.accept();
socketChannel.configureBlocking(假);
socketChannel.register(selectionKey.selector(),selectionKey.OP_READ);
sessions.put(socketChannel,newbytebuilder());
}else if(selectionKey.isReadable()){
最终SocketChannel SocketChannel=(SocketChannel)selectionKey.channel();
final ByteBuffer ByteBuffer=ByteBuffer.allocate(Connection.MAX\u BUFFER\u SIZE);
最终整数bytesRead=socketChannel.read(byteBuffer);
如果(字节读取!=-1){
字节[]数据=新字节[字节读取];
System.arraycopy(byteBuffer.array(),0,数据,0,字节读取);
布尔自动关闭=真;
if(ConnectionHost.this.handle(this.getConnectionCreator().createConnection(socketChannel),数据)){
自动关闭=真;
}否则自动关闭=错误;
如果(自动关闭){
会话。移除(socketChannel);
socketChannel.close();
}否则{
if(!sessions.containsKey(socketChannel))sessions.put(socketChannel,new ByteBuilder());
}
}
}else抛出新的BloumException(“不支持给定的键”);
}否则抛出新的BloumException(“密钥不再有效”);
}
}

问题其实很简单,经过一番尝试,我终于找到了解决办法。我忘了在阅读过程中添加中断语句。我还添加了一个简单的算法,可以删除1gb字节缓冲区导致的0字节

final ByteBuffer byteBuffer = ByteBuffer.allocate(DefaultConnectionCreator.this.getDefaultBufferSize());

                try {
                    while(socketChannel.read(byteBuffer) != -1){    
                        //byteBuffer.clear();
                    }
                } catch (IOException exception) {
                    exception.printStackTrace();
                    throw new BloumException(exception.getMessage());
                }
                final ArrayList<Byte> bytes = new ArrayList<>();

                Integer current = 0;

                for(Integer i = 0; i<byteBuffer.array().length; i++){
                    final byte b = byteBuffer.array()[i];
                    if(b==0){
                        Boolean okay = false;
                        for(Integer x = i+1; x<byteBuffer.array().length; x++){
                            if(byteBuffer.array()[x]!=0){
                                okay=true;
                                break;
                            }
                        }
                        if(!okay){
                            break;
                        }
                        bytes.add(b);
                    }else bytes.add(b);

                    current=current+1;
                }
                return this.toPrimitive(bytes.toArray(new Byte[bytes.size()]));
final ByteBuffer ByteBuffer=ByteBuffer.allocate(DefaultConnectionCreator.this.getDefaultBufferSize());
试一试{
while(socketChannel.read(byteBuffer)!=-1{
//byteBuffer.clear();
}
}捕获(IOException异常){
异常。printStackTrace();
抛出新的BloumException(exception.getMessage());
}
最终ArrayList字节数=新ArrayList();
整数电流=0;

对于(整数i=0;i你好,你有很多错误

  • 写入前需要翻转缓冲区
  • 如果读取为-1,则必须关闭频道
  • 不要创建1GB字节的缓冲区—使用的大小是256、1024、4096、8196—我建议使用4096
  • 使用直接缓冲区,直接内存已证明其I/O速度更快,因为它是 没有被垃圾收集器中断
  • 没有用于布尔值的if语句,请将布尔值设置为等于该语句
  • 不要有忽略读取字节的while循环,如果为0,则表示您 在套接字打开之前,不要读取导致循环的任何内容 封闭的
  • 我很确定你删除0的循环是 删除未添加的数据,但您可以这样做
    Arrays.copyOfRange(buffer.array(),0,buffer.position())
    或者 翻转缓冲区,然后
    Arrays.copyOfRange(buffer.array(),0,
    缓冲区限制())

  • 这是因为在对数据执行任何操作之前,您一直在读取到流的末尾。与
    SocketChannel
    的发送无关。在处理任何数据之前,此代码仍将读取到流的末尾,这是这里的实际问题。删除零的循环仅存在于此,因为他已丢弃了
    read()
    ,这会告诉他停在哪里。