선택기를 사용해야합니다. 먼저 이벤트를 수신하는 선택기를 만들 :
SelectionKey acceptKey = server.register(selector, SelectionKey.OP_ACCEPT);
그런 다음 당신은 그들이에서 와서 (당신이 이벤트를 처리하기 위해 선택기를 사용해야합니다
이
Selector selector = Selector.open()
그런 다음 당신은 선택과 ServerSocketChannel을 등록해야 프로세스의 "콜백"부분으로 생각할 수 있습니다
while(true){
//how many channel keys are available
int available = selector.select();
//select is blocking, but should only return if available is >0, this is more of a sanity check
if(available == 0) continue;
Iterator<SelectionKey> keys = selector.selectedKeys().iterator();
while(keys.hasNext()){
SelectionKey key = keys.next();
keys.remove();
//someone is trying to connect to the server socket
if(key.isAcceptable()) doAccept(key);
//someone is sending us data
else if(key.isReadable()) doRead(key);
//we are trying to (and can) send data
else if(key.isWritable()) doWrite(key);
}
는 선택 키가 INF가 포함됩니다 키 동의를 들어 고기가 doAccept(), doRead() 및 doWrite()에있을 것입니다. 새로운 소켓을 만들기위한 오리온. 선택기에서받은 이벤트가 연결 (예를 들어,이 게임의 선수가 될 수 있음)에 기인 할 수 있도록
doAccept(SelectionKey key){
//create the new socket
SocketChannel socket = ((ServerSocketChannel)key.channel()).accept();
//make it non-blocking as well
socket.configureBlocking(false);
...
//here you would likely have some code to init your game objects/communication protocol, etc. and generate an identifier object (used below).
//and be able to find the socket created above
...
//Since it is non blocking it needs a selector as well, and we register for both read and write events
SelectionKey socketKey = socket.register(selector, SelectionKey.OP_READ|SelectionKey.OP_WRITE);
// so we can identify the events as they come in
socketKey.attach(someSocketIndentifier);
}
마지막 줄은 키에 어떤 객체를 추가합니다. 이제 새로운 연결을 수락 할 수 있으며 읽고 쓰는 것이 필요합니다. 쓰기에 대한 유사
doRead(SelectionKey key){
//here we retrieve the key we attached earlier, so we now what to do/wheer the data is coming from
MyIdentifierType myIdentifier = (MyIdentifierType)key.attachment();
//This is then used to get back to the SocketChannel and Read the Data
myIdentifier.readTheData();
}
는
doWrite(SelectionKey key){
//here we retrieve the key we attached earlier, so we now what to do/wheer the data is coming from
MyIdentifierType myIdentifier = (MyIdentifierType)key.attachment();
//This is then used to get back to the SocketChannel and Read the Data
myIdentifier.getSocketHandler().writePendingData();
}
독서는 단지의 데이터를 준비하는 SocketChannel에는이 (의 ByteBuffer)을 읽는 (그 변종 또는 하나)를 호출 한 후 ByteBuffer를 생성하고, 정직하고 공정하게하다 채널이 비어있을 때까지. 당신이 클래스에 버퍼를 관리하기 위해 적절한 코드가 필요합니다
class MyNetworkClass{
ByteBuffer writeBuffer = ByteBuffer.allocate(1024);
SocketChannel commchannel; //from the server accept processing
...
public void write(byte[] data){
//here the class writeBuffer object is filled with the data
//but it isn't actually sent over the socket
...
}
public void writePendingData(){
//here actually write the data to the socket
commchannel.write(writeBuffer);
}
}
참고 : 일반적으로는 쓰기 이벤트를받을 때까지 데이터가 기록되는 버퍼 할 것 같은
쓰기에는 약간 까다 롭습니다 처리 중에 throw 될 수있는 각종의 예외 뿐만이 아니라, 버퍼 내의 모든 데이터가 소켓에 기입 해지지 않은 경우, 기입 해 대기 중의 메소드로 적절하게 변경하는 이벤트 희망이 당신을 시작하는 데 도움이됩니다.
비 차단 입출력 대신 다중 스레드를 사용하는 것이 좋습니다. –