2016-07-22 313 views

回答

0

这很有道理。套接字通道始终可读,且read始终返回EOF。

一旦您从通道读取EOF,您需要将其从选择器中删除。

+0

我应该怎么做才能避免呢? – user6625198

0

这是我的代码

package com.socket.Server; 
 

 

 
import java.io.IOException; 
 
import java.net.InetSocketAddress; 
 
import java.net.ServerSocket; 
 
import java.net.Socket; 
 
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.nio.charset.Charset; 
 
import java.util.HashMap; 
 
import java.util.Map; 
 
import java.util.Set; 
 
    
 
public class ImSocketServer { 
 
    private int port = 8888; 
 
    private Charset cs = Charset.forName("gbk"); 
 
    private static ByteBuffer sBuffer = ByteBuffer.allocate(1024); 
 
    private static ByteBuffer rBuffer = ByteBuffer.allocate(1024); 
 
    private Map<String, SocketChannel> clientsMap = new HashMap<String, SocketChannel>(); 
 
    private static Selector selector; 
 
     
 
    public ImSocketServer(int port){ 
 
     this.port = port; 
 
     try { 
 
      init(); 
 
     } catch (Exception e) { 
 
      e.printStackTrace(); 
 
     } 
 
    } 
 
    private void init() throws IOException{ 
 

 
    \t ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); 
 
     serverSocketChannel.configureBlocking(false); 
 
     ServerSocket serverSocket = serverSocketChannel.socket(); 
 
     serverSocket.bind(new InetSocketAddress(port)); 
 
     selector = Selector.open(); 
 
     serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); 
 
     System.out.println("server start on port:"+port); 
 
    } 
 

 
    private void listen(){ 
 
     while (true) { 
 
      try { 
 
      \t System.out.println(selector.select()); 
 
       Set<SelectionKey> selectionKeys = selector.selectedKeys(); 
 
       for(SelectionKey key : selectionKeys){ 
 
        
 
        try{ 
 
        \t handle(key); 
 
         
 
         } 
 
         catch(Exception e){ 
 
         \t System.out.println("挂了"); 
 
         } 
 
       } 
 
       selectionKeys.clear(); 
 
       selector.selectedKeys().clear(); 
 
      } catch (Exception e) { 
 
       e.printStackTrace(); 
 
       break; 
 
      } 
 
       
 
     } 
 
    } 
 
    
 
    private void handle(SelectionKey selectionKey) throws IOException { 
 
     ServerSocketChannel server = null; 
 
     SocketChannel client = null; 
 
     String receiveText=null; 
 
     int count=0; 
 
     if (selectionKey.isAcceptable()) { 
 
      server = (ServerSocketChannel) selectionKey.channel(); 
 
      client = server.accept(); 
 
      client.configureBlocking(false); 
 
      client.register(selector, SelectionKey.OP_READ); 
 
     } else if (selectionKey.isReadable()) { 
 
      client = (SocketChannel) selectionKey.channel(); 
 
      rBuffer.clear(); 
 
      count = client.read(rBuffer); 
 
      if (count > 0) { 
 
       rBuffer.flip(); 
 
       receiveText = String.valueOf(cs.decode(rBuffer).array()); 
 
       System.out.println(client.toString()+":"+receiveText); 
 
       dispatch(client, receiveText); 
 
       client = (SocketChannel) selectionKey.channel(); 
 
       client.register(selector, SelectionKey.OP_READ); 
 
      } 
 
     } 
 
    } 
 

 
    private void dispatch(SocketChannel client,String info) throws IOException{ 
 
     Socket s = client.socket(); 
 
     String name = "["+s.getInetAddress().toString().substring(1)+":"+Integer.toHexString(client.hashCode())+"]"; 
 
     if(!clientsMap.isEmpty()){ 
 
      for(Map.Entry<String, SocketChannel> entry : clientsMap.entrySet()){ 
 
       SocketChannel temp = entry.getValue(); 
 
       if(!client.equals(temp)){ 
 
        sBuffer.clear(); 
 
        sBuffer.put((name+":"+info).getBytes()); 
 
        sBuffer.flip(); 
 
        temp.write(sBuffer); 
 
       } 
 
      } 
 
     } 
 
     clientsMap.put(name, client); 
 
    } 
 
    public static void main(String[] args) throws IOException { 
 
     ImSocketServer server = new ImSocketServer(7777); 
 
     server.listen(); 
 
    } 
 
}