Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/309.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
Java 写入NIO socketchannel引发IOException:资源暂时不可用_Java_Nio - Fatal编程技术网

Java 写入NIO socketchannel引发IOException:资源暂时不可用

Java 写入NIO socketchannel引发IOException:资源暂时不可用,java,nio,Java,Nio,我有一个NIO程序,它监听两个IPC连接。IPC基于UnixDomain套接字并使用jnr unixdomainsocket库,该库允许我使用可选的ServerSocketChannels和SocketChannels包装UDS。我之所以使用这个库,是因为我想用非阻塞IO运行程序,但在linux select调用上阻塞。我编写了一个名为NIODriver的类,它实现了通道接受和读取函数(代码如下)Iam运行两个NIODriver类实例(下面的代码),每个IPC管道绑定一个实例。我的主类获得Jav

我有一个NIO程序,它监听两个IPC连接。IPC基于UnixDomain套接字并使用jnr unixdomainsocket库,该库允许我使用可选的ServerSocketChannels和SocketChannels包装UDS。我之所以使用这个库,是因为我想用非阻塞IO运行程序,但在linux select调用上阻塞。我编写了一个名为NIODriver的类,它实现了通道接受和读取函数(代码如下)

Iam运行两个NIODriver类实例(下面的代码),每个IPC管道绑定一个实例。我的主类获得Java选择器的一个实例,并向选择器注册NIODriver的ServerSocketChannel的两个实例。他们最初是以接受利息登记的。然后程序调用select并在那里等待。当外部程序连接时,main类获取与管道关联的NIODriver实例并调用其acceptConnection方法。这将在其内部创建SocketChannel实例,该实例在具有读取兴趣的同一选择器上注册。这两种情况都会发生,因为我有两个外部程序,一个连接到每个管道。

一个外部程序(我们称之为A)连续向NIO程序泵送数据(一个12字节的数据包)。select会不断触发并调用NIODriver的channelRead方法,该方法读取数据,然后获取对另一个NIODriver实例的引用并调用其update()方法。update方法将数据写入第二个外部程序(比如B)。当我在循环中运行它时,偶尔会得到IOException:resource暂时不可用。

下面是NIODriver类的代码

公共类驱动程序{

int did;
String name;
String udsName;

UnixSocketAddress sockAddress;
UnixServerSocketChannel serverChannel;
Selector selector;
UnixSocketChannel channel;
ByteBuffer inbuf;
ByteBuffer outbuf;

int ctr = 0;

public NIODriver(int id, String name, String pipename) {
    this.did = id;
    this.name = name;
    this.udsName = pipename;

    this.sockAddress = new UnixSocketAddress(new File(udsName));
    inbuf = ByteBuffer.allocate(12*100);
    outbuf = ByteBuffer.allocate(12*100);
}

public void setSelector(Selector sel){
    this.selector = sel;
}

public boolean openConnection(){
    try {
        serverChannel = UnixServerSocketChannel.open();            
        serverChannel.configureBlocking(false);
        serverChannel.socket().bind(sockAddress);  
        serverChannel.register(selector, SelectionKey.OP_ACCEPT, this);
        return true;
    } catch (IOException ex) {
        Logger.getLogger(NIODriver.class.getName()).log(Level.SEVERE, null, ex);
        return false;
    }
}

public boolean acceptConnection(){
    try {
            System.out.println("accepting connection");                
            channel = serverChannel.accept();
            channel.configureBlocking(false);
            channel.register(selector, SelectionKey.OP_READ, this); 
            return true;
        } catch (IOException ex) {
            System.out.println("acceptConnection failed");
            ex.printStackTrace(System.out);
            return false;
        }
}

public int channelRead(){
    try {                
        int n = channel.read(inbuf); 
        if(n == -1)throw new DriverDisconnectedException("Channel.read returned -1");
        /* Important: Call flip before checking number of readable bytes */
        inbuf.flip();
        int num = inbuf.remaining();            
        if(num<12){
            /* Going to return since there is not enough bytes. Set buffer
                back to read mode before returning.
            */
            inbuf.compact();
            return 0;
        }

        int id = inbuf.getInt();            
        double dval = inbuf.getDouble();
    inbuf.compact();
    if(dval == 0){
    System.out.println("Read value="+dval); 
    }

    for(NIODriver obs: gt.observers){
        obs.update(id,dval);
    }                   

        return 0;
    } catch (IOException ex) {
        ex.printStackTrace(System.out);
        return 0;
    } catch (DriverDisconnectedException ex) {
        Logger.getLogger(NIODriver.class.getName()).log(Level.SEVERE, null, ex);
        return -1;
    } 
}


public void update(int id, double val){
    try {
        outbuf.putInt(id);
        outbuf.putDouble(val);
        outbuf.flip();
        channel.write(outbuf);
        outbuf.compact();
    } catch (IOException ex) {
        Logger.getLogger(NIODriver.class.getName()).log(Level.SEVERE, null, ex);
    } 
}
int-did;
字符串名;
字符串udsName;
UnixSocketAddress sockAddress;
unixserversocketchannelserverchannel;
选择器;
UnixSocketChannel通道;
ByteBuffer inbuf;
比特布弗爆发;
int ctr=0;
公共NIODriver(int-id、字符串名称、字符串管道名称){
this.did=id;
this.name=名称;
this.udsName=管道名称;
this.sockAddress=newunixsocketAddress(新文件(udsName));
inbuf=字节缓冲分配(12*100);
exputf=字节缓冲分配(12*100);
}
公共选择器(选择器sel){
this.selector=sel;
}
公共布尔openConnection(){
试一试{
serverChannel=UnixServerSocketChannel.open();
serverChannel.configureBlocking(false);
serverChannel.socket().bind(sockAddress);
serverChannel.register(选择器,SelectionKey.OP_ACCEPT,this);
返回true;
}捕获(IOEX异常){
Logger.getLogger(NIODriver.class.getName()).log(Level.SEVERE,null,ex);
返回false;
}
}
公共布尔接受连接(){
试一试{
System.out.println(“接受连接”);
channel=serverChannel.accept();
信道配置阻塞(假);
通道寄存器(选择器,SelectionKey.OP_READ,this);
返回true;
}捕获(IOEX异常){
System.out.println(“acceptConnection失败”);
例如printStackTrace(系统输出);
返回false;
}
}
公共int channelRead(){
试试{
int n=信道读取(inbuf);
如果(n==-1)抛出新的DriverDisconnectedException(“Channel.read返回-1”);
/*重要提示:在检查可读字节数之前调用flip*/
inbuf.flip();
int num=inbuf.remaining();

如果(NUMCA)您可以发布框架代码,以更清楚地演示事件序列?以及堆栈跟踪?并编辑您的问题以删除不正确的部分吗?感谢您的关注Neil和EJP。对于我的长时间延迟表示歉意。我已经完全重写了问题。请审阅。