java nio套接字未检测到机器何时进入睡眠或休眠状态

java nio套接字未检测到机器何时进入睡眠或休眠状态,java,sockets,nio,sleep-mode,hibernate-mode,Java,Sockets,Nio,Sleep Mode,Hibernate Mode,下面是我的套接字服务器和客户端组件的简化版本 主要目标是让客户机检测服务器何时停机,让服务器检测客户机何时停机 当客户机或服务器被终止(获取IOException“远程主机强制关闭了现有连接”)时(在Windows上),这一点非常有效 我还想检测运行客户机或服务器的机器何时进入睡眠(或休眠),最终使用相同的机制 相反,当前的行为是未检测到“另一台机器将进入睡眠”事件,当机器被唤醒时,连接再次处于活动状态。此时,如前所述检测到“进程停止”事件 在客户机进入睡眠状态的情况下,罪魁祸首似乎是“sele

下面是我的套接字服务器和客户端组件的简化版本

主要目标是让客户机检测服务器何时停机,让服务器检测客户机何时停机

当客户机或服务器被终止(获取IOException“远程主机强制关闭了现有连接”)时(在Windows上),这一点非常有效

我还想检测运行客户机或服务器的机器何时进入睡眠(或休眠),最终使用相同的机制

相反,当前的行为是未检测到“另一台机器将进入睡眠”事件,当机器被唤醒时,连接再次处于活动状态。此时,如前所述检测到“进程停止”事件

在客户机进入睡眠状态的情况下,罪魁祸首似乎是“selector.selectedKeys()”没有返回与睡眠机器连接的密钥

Windows上的套接字实现中是否缺少此功能

有人对如何解决这个问题有什么建议吗

package test;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;

public class TestServer {
    private ByteBuffer _inBuf;
    private int _serverPort;

    public static void main(String[] args) {
        TestServer server = new TestServer(7071);
        server.start();
    }

    public TestServer(int serverPort) {
        _serverPort = serverPort;
    }

    public void start() {
        _inBuf = ByteBuffer.allocate(512);
        System.out.println("Server starting on port "+_serverPort);
        new Thread() {
            public void run() {
                try {
                    Selector selector = Selector.open();
                    ServerSocketChannel server = ServerSocketChannel.open();
                    server.socket().bind(new InetSocketAddress(_serverPort));
                    server.configureBlocking(false);
                    SelectionKey serverKey = server.register(selector, SelectionKey.OP_ACCEPT);

                    while (true) {
                        selector.select();
                        Set<SelectionKey> keys = selector.selectedKeys();
                        for (Iterator<SelectionKey> i = keys.iterator(); i.hasNext(); ) {
                            SelectionKey key = i.next();
                            i.remove();
                            if (key == serverKey) {
                                if (key.isAcceptable()) {
                                    System.out.println("acceptable server key "+Integer.toHexString(key.hashCode()));
                                    try {
                                        SocketChannel client = server.accept();
                                        client.configureBlocking(false);
                                        SelectionKey clientKey = client.register(selector, SelectionKey.OP_READ);
                                        System.out.println("registered client key "+Integer.toHexString(clientKey.hashCode()));
                                    } catch (IOException x) {
                                        x.printStackTrace();
                                    }
                                }
                            } else {
                                if (!key.isReadable()) continue;
                                SocketChannel client = (SocketChannel) key.channel();
                                System.out.println("reading "+Integer.toHexString(key.hashCode()));
                                try {
                                    int no = client.read(_inBuf);
                                    if (no<0) throw new IOException("reached end-of-stream"+Integer.toHexString(key.hashCode()));
                                    if (no>0) System.out.println("read "+no+" bytes from "+Integer.toHexString(key.hashCode()));
                                } catch (IOException x) {
                                    System.out.println(x.getMessage()+" "+Integer.toHexString(key.hashCode()));
                                    key.cancel();
                                    try {
                                        client.close();
                                    } catch (IOException ignore) {
                                        ignore.printStackTrace();
                                    }
                                    continue;
                                }
                                _inBuf.flip();
                                _inBuf.compact();
                            }
                        }
                    }
                } catch (Exception x) {
                    x.printStackTrace();
                }
            }
        }.start();
    }
}
封装测试;
导入java.io.IOException;
导入java.net.InetSocketAddress;
导入java.nio.ByteBuffer;
导入java.nio.channels.SelectionKey;
导入java.nio.channels.Selector;
导入java.nio.channels.ServerSocketChannel;
导入java.nio.channels.SocketChannel;
导入java.util.Iterator;
导入java.util.Set;
公共类测试服务器{
私人ByteBuffer_inBuf;
专用int_服务器端口;
公共静态void main(字符串[]args){
TestServer服务器=新的TestServer(7071);
server.start();
}
公共测试服务器(int服务器端口){
_serverPort=serverPort;
}
公开作废开始(){
_inBuf=ByteBuffer.allocate(512);
System.out.println(“服务器在端口上启动”+_serverPort);
新线程(){
公开募捐{
试一试{
选择器=选择器。打开();
ServerSocketChannel服务器=ServerSocketChannel.open();
server.socket().bind(新的InetSocketAddress(_serverPort));
server.configureBlocking(false);
SelectionKey serverKey=server.register(选择器,SelectionKey.OP_ACCEPT);
while(true){
selector.select();
设置键=选择器。selectedKeys();
for(迭代器i=keys.Iterator();i.hasNext();){
SelectionKey=i.next();
i、 删除();
if(key==serverKey){
if(key.isAcceptable()){
System.out.println(“可接受的服务器密钥”+Integer.toHexString(key.hashCode());
试一试{
SocketChannel client=server.accept();
client.configureBlocking(false);
SelectionKey clientKey=client.register(选择器,SelectionKey.OP_READ);
System.out.println(“注册的客户端密钥”+Integer.toHexString(clientKey.hashCode());
}捕获(IOX异常){
x、 printStackTrace();
}
}
}否则{
如果(!key.isReadable())继续;
SocketChannel客户端=(SocketChannel)key.channel();
System.out.println(“读取”+Integer.toHexString(key.hashCode());
试一试{
int no=client.read(_inBuf);
if(no0)System.out.println(“从”+Integer.toHexString(key.hashCode())读取”+no+”字节);
}捕获(IOX异常){
System.out.println(x.getMessage()+“”+Integer.toHexString(key.hashCode());
键。取消();
试一试{
client.close();
}捕获(IOException忽略){
ignore.printStackTrace();
}
继续;
}
_inBuf.flip();
_inBuf.compact();
}
}
}
}捕获(异常x){
x、 printStackTrace();
}
}
}.start();
}
}

封装测试;
导入java.io.IOException;
导入java.net.InetSocketAddress;
导入java.net.SocketAddress;
导入java.nio.ByteBuffer;
导入java.nio.channels.SocketChannel;
公共类测试客户端{
私有静态最终整数_connectionTimeoutNanos=10*1000000;
私有字符串\u服务器主机;
专用int_服务器端口;
专用SocketChannel\u通道=null;
私人ByteBuffer_inBuf;
公共静态void main(字符串[]args){
TestClient=新的TestClient(“192.168.1.180”,7071);
client.start();
}
公共测试客户端(字符串服务器主机,int服务器端口){
_serverHost=serverHost;
_serverPort=serverPort;
}
公开作废开始(){
_inBuf=ByteBuffer.allocate(512);
ClientThread线程=新ClientThread();
thread.start();
}
私有类ClientThread扩展线程{
@凌驾
公开募捐{
System.out.println(“客户端连接到”+\u serverHost+:“+\u serverPort”);
SocketAddress
package test;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;

public class TestClient {
    private static final int _connectionTimeoutNanos = 10 * 1000000;
    private String _serverHost;
    private int _serverPort;
    private SocketChannel _channel = null;
    private ByteBuffer _inBuf;

    public static void main(String[] args) {
        TestClient client = new TestClient("192.168.1.180", 7071);
        client.start();
    }

    public TestClient(String serverHost, int serverPort) {
        _serverHost = serverHost;
        _serverPort = serverPort;
    }

    public void start() {
        _inBuf = ByteBuffer.allocate(512);
        ClientThread thread = new ClientThread();
        thread.start();
    }

    private class ClientThread extends Thread {
        @Override
        public void run() {
            System.out.println("Client connecting to "+_serverHost+":"+_serverPort);
            SocketAddress socketAddress = new InetSocketAddress(_serverHost, _serverPort);
            while (true) {
                boolean connected = false;
                try {
                    _channel = SocketChannel.open();
                    _channel.configureBlocking(false);
                    try {
                        connected = _channel.connect(socketAddress);
                    } catch (IOException x) {
                        try {
                            _channel.close();
                        } catch (Throwable suppressed) {
                            x.addSuppressed(suppressed);
                        }
                        throw x;
                    }
                    long nanoStart = System.nanoTime();
                    while (!connected) {
                        connected = _channel.finishConnect();
                        if (!connected && (nanoStart+_connectionTimeoutNanos < System.nanoTime())) {
                            throw new IOException("Non blocking connect failed");
                        }
                    }

                    _channel.socket().setSoLinger(true, 10);
                    System.out.println("Connected to "+_serverHost+":"+_serverPort);

                    while (true) {
                        if (!readFromChannel()) break;
                    }

                    System.out.println("Disconnected from "+_serverHost+":"+_serverPort);
                } catch (IOException x) {
                    if (connected) {
                        System.out.println("Disconnected from "+_serverHost+":"+_serverPort+" "+x.getMessage());
                    }
                }
                try {Thread.sleep(1000);} catch (InterruptedException x) {}
            }
        }
    }

    public boolean readFromChannel() throws IOException {
        int no = _channel.read(_inBuf);
        if (no<0) {
            return false;
        }
        if (no>0) System.out.println("read "+no+" bytes from "+_serverHost+":"+_serverPort);
        _inBuf.flip();
        _inBuf.compact();
        return true;
    }
}
channel.setOption(StandardSocketOptions.SO_KEEPALIVE, true);
client.socket().setKeepAlive(true);
client.setOption(StandardSocketOptions.SO_KEEPALIVE, true);
_channel.socket().setSoLinger(true, 10);
_channel.socket().setKeepAlive(true);