문제

각 준비 채널에 대해 메시지를 결정하고 보낼 수있는 일반적인 방식으로 선택기를 사용하는 대신 현재 준비가 된 연결을 선택하고 메시지를 보내려고합니다.

아마도 이것은 모든 채널을 선택기로 던져 읽고 읽을 준비가 된 후 읽을 준비가 된 다음 글을 쓰기 위해 동일하게 수행 한 다음 준비된 사람들 중에서 선택하여 수행 할 수 있습니다.

이것은 좋은 생각입니까, 이것을하는 더 좋은 방법이 있습니까? 그리고 무엇을 조심해야합니까? 예를 들어, ROX 튜토리얼"OP Read와 OP Write를 혼합하려고하면 빨리 문제를 일으킬 수 있습니다.이 작업을 수행하면 Sun Windows 구현이 교착 상태로 나타났습니다." 여기에 비슷한 Gotchas가 있습니까? 구현하는 가장 좋은 방법은 무엇입니까 :

boolean isReadyForRead(SocketChannel c);
boolean isReadyForWrite(SocketChannel c);
도움이 되었습니까?

해결책

이런 식은 어때?

public static boolean isReadyForRead(SocketChannel socket) throws IOException {
    return isReady(socket, SelectionKey.OP_READ);
}

public static boolean isReadyForWrite(SocketChannel socket) throws IOException {
    return isReady(socket, SelectionKey.OP_WRITE);
}

public static boolean isReady(SocketChannel socket, int op) throws IOException {
    // Setup
    if (socket.isBlocking()) 
        throw new IllegalArgumentException("Socket must be in non-blocking mode");

    Selector selector = SelectorProvider.provider().openSelector();
    socket.register(selector, op);

    // Real work
    if (selector.selectNow() == 0)
        return false;
    // Just in case selector has other keys
    return selector.selectedKeys().contains(socket.keyFor(selector));
}

이 호출은 매번 설정을 수행하기 때문에 매우 비효율적입니다. 둘러싸는 클래스가있는 경우이를 옮겨야합니다. 선택기가 하나의 키 만 포함되어 있으면 마지막 줄을 변경할 수 있습니다.return true;".

나는 단지 재미를 위해 이것을하고 있습니다. 이것이 유용 할 시나리오를 생각할 수 없습니다. Select ()는 소켓의 상태를 효율적으로 알려주도록 설계되었으며 모든 사람이 직접 사용해야합니다.

다른 팁

선택 키를 사용하여 선택기가 깨어날 때 소켓이 읽거나 쓸 준비가되었는지 확인해야합니다.

여기에 있습니다 매우 NIO 서버 및 클라이언트 작성에 대한 유용한 자습서 http://rox-xmlrpc.sourceforge.net/niotut/

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top