java socket回调_Java ServerSocketChannel SocketChannel(回调)
您需要使用選擇器.首先創建一個Selector來接收事件:
Selector selector = Selector.open()
然后,您需要使用選擇器注冊ServerSocketChannel:
SelectionKey acceptKey = server.register(selector, SelectionKey.OP_ACCEPT);
然后,您需要使用選擇器來處理事件(您可以將其視為流程的“回調”部分:
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 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);
}
肉將在doAccept(),doRead()和doWrite()中.對于接受鍵,選擇鍵將包含用于創建新Socket的信息.
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();
}
讀取是相當簡單的,您只需創建一個ByteBuffer,然后調用SocketChannels讀取(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);
}
}
請注意,如果不是緩沖區中的所有數據都寫入套接字,則需要適當的代碼來管理類中的緩沖區(如果它已滿),或者在寫入暫掛方法中適當地修改緩沖區,以及在此過程中可能拋出的各種異常.希望這有助于您入門.
總結
以上是生活随笔為你收集整理的java socket回调_Java ServerSocketChannel SocketChannel(回调)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java sendmessage_Sen
- 下一篇: java流方式接收pdf_java –