氟塑料离心泵www.buybeng.com

jquery教程http://www.software8.co/wzjs/jquery/

java nio SocketChannel 服务器端与多客户端 信息交互(聊天功能)

服务器端: 
Java代码 : 
  1. import java.io.IOException;  
  2. import java.net.InetSocketAddress;  
  3. import java.net.ServerSocket;  
  4. import java.net.Socket;  
  5. import java.nio.ByteBuffer;  
  6. import java.nio.channels.SelectionKey;  
  7. import java.nio.channels.Selector;  
  8. import java.nio.channels.ServerSocketChannel;  
  9. import java.nio.channels.SocketChannel;  
  10. import java.nio.charset.Charset;  
  11. import java.util.HashMap;  
  12. import java.util.Map;  
  13. import java.util.Set;  
  14.   
  15. public class NIOSServer {  
  16.     private int port = 8888;  
  17.     //解码buffer  
  18.     private Charset cs = Charset.forName("gbk");  
  19.     /*接受数据缓冲区*/  
  20.     private static ByteBuffer sBuffer = ByteBuffer.allocate(1024);  
  21.     /*发送数据缓冲区*/  
  22.     private static ByteBuffer rBuffer = ByteBuffer.allocate(1024);  
  23.     /*映射客户端channel */  
  24.     private Map<String, SocketChannel> clientsMap = new HashMap<String, SocketChannel>();  
  25.     private static Selector selector;  
  26.       
  27.     public NIOSServer(int port){  
  28.         this.port = port;  
  29.         try {  
  30.             init();  
  31.         } catch (Exception e) {  
  32.             e.printStackTrace();  
  33.         }  
  34.     }  
  35.     private void init() throws IOException{  
  36.         /* 
  37.          *启动服务器端,配置为非阻塞,绑定端口,注册accept事件 
  38.          *ACCEPT事件:当服务端收到客户端连接请求时,触发该事件 
  39.          */  
  40.         ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();  
  41.         serverSocketChannel.configureBlocking(false);  
  42.         ServerSocket serverSocket = serverSocketChannel.socket();  
  43.         serverSocket.bind(new InetSocketAddress(port));  
  44.         selector = Selector.open();  
  45.         serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);  
  46.         System.out.println("server start on port:"+port);  
  47.     }  
  48.     /** 
  49.      * 服务器端轮询监听,select方法会一直阻塞直到有相关事件发生或超时 
  50.      */  
  51.     private void listen(){  
  52.         while (true) {  
  53.             try {  
  54.                 selector.select();//返回值为本次触发的事件数  
  55.                 Set<SelectionKey> selectionKeys = selector.selectedKeys();  
  56.                 for(SelectionKey key : selectionKeys){  
  57.                     handle(key);  
  58.                 }  
  59.                 selectionKeys.clear();//清除处理过的事件  
  60.             } catch (Exception e) {  
  61.                 e.printStackTrace();  
  62.                 break;  
  63.             }  
  64.               
  65.         }  
  66.     }  
  67.     /** 
  68.      * 处理不同的事件 
  69.     */  
  70.     private void handle(SelectionKey selectionKey) throws IOException {  
  71.         ServerSocketChannel server = null;  
  72.         SocketChannel client = null;  
  73.         String receiveText=null;  
  74.         int count=0;  
  75.         if (selectionKey.isAcceptable()) {  
  76.             /* 
  77.              * 客户端请求连接事件 
  78.              * serversocket为该客户端建立socket连接,将此socket注册READ事件,监听客户端输入 
  79.              * READ事件:当客户端发来数据,并已被服务器控制线程正确读取时,触发该事件 
  80.              */  
  81.             server = (ServerSocketChannel) selectionKey.channel();  
  82.             client = server.accept();  
  83.             client.configureBlocking(false);  
  84.             client.register(selector, SelectionKey.OP_READ);  
  85.         } else if (selectionKey.isReadable()) {  
  86.             /* 
  87.              * READ事件,收到客户端发送数据,读取数据后继续注册监听客户端 
  88.              */  
  89.             client = (SocketChannel) selectionKey.channel();  
  90.             rBuffer.clear();  
  91.             count = client.read(rBuffer);  
  92.             if (count > 0) {  
  93.                 rBuffer.flip();  
  94.                 receiveText = String.valueOf(cs.decode(rBuffer).array());  
  95.                 System.out.println(client.toString()+":"+receiveText);  
  96.                 dispatch(client, receiveText);  
  97.                 client = (SocketChannel) selectionKey.channel();  
  98.                 client.register(selector, SelectionKey.OP_READ);  
  99.             }  
  100.         }   
  101.     }  
  102.       
  103.     /** 
  104.      * 把当前客户端信息 推送到其他客户端 
  105.      */  
  106.     private void dispatch(SocketChannel client,String info) throws IOException{  
  107.         Socket s = client.socket();  
  108.         String name = "["+s.getInetAddress().toString().substring(1)+":"+Integer.toHexString(client.hashCode())+"]";  
  109.         if(!clientsMap.isEmpty()){  
  110.             for(Map.Entry<String, SocketChannel> entry : clientsMap.entrySet()){  
  111.                 SocketChannel temp = entry.getValue();  
  112.                 if(!client.equals(temp)){  
  113.                     sBuffer.clear();  
  114.                     sBuffer.put((name+":"+info).getBytes());  
  115.                     sBuffer.flip();  
  116.                     //输出到通道  
  117.                     temp.write(sBuffer);  
  118.                 }  
  119.             }  
  120.         }  
  121.         clientsMap.put(name, client);  
  122.     }  
  123.     public static void main(String[] args) throws IOException {  
  124.         NIOSServer server = new NIOSServer(7777);  
  125.         server.listen();  
  126.     }  
  127. }  
客户端,可运行启动多个: 
Java代码:  
  1. import java.io.BufferedReader;  
  2. import java.io.IOException;  
  3. import java.io.InputStreamReader;  
  4. import java.net.InetSocketAddress;  
  5. import java.nio.ByteBuffer;  
  6. import java.nio.channels.SelectionKey;  
  7. import java.nio.channels.Selector;  
  8. import java.nio.channels.SocketChannel;  
  9. import java.util.Date;  
  10. import java.util.Set;  
  11.   
  12. public class NIOClient {  
  13.     /*发送数据缓冲区*/  
  14.     private static ByteBuffer sBuffer = ByteBuffer.allocate(1024);  
  15.     /*接受数据缓冲区*/  
  16.     private static ByteBuffer rBuffer = ByteBuffer.allocate(1024);  
  17.     /*服务器端地址*/  
  18.     private InetSocketAddress SERVER;  
  19.     private static Selector selector;  
  20.     private static SocketChannel client;  
  21.     private static String receiveText;  
  22.     private static String sendText;  
  23.     private static int count=0;  
  24.       
  25.     public NIOClient(int port){  
  26.         SERVER = new InetSocketAddress("localhost", port);  
  27.         init();  
  28.     }  
  29.     public void init(){  
  30.         try {  
  31.            /* 
  32.              * 客户端向服务器端发起建立连接请求 
  33.              */  
  34.             SocketChannel socketChannel = SocketChannel.open();  
  35.             socketChannel.configureBlocking(false);  
  36.             selector = Selector.open();  
  37.             socketChannel.register(selector, SelectionKey.OP_CONNECT);  
  38.             socketChannel.connect(SERVER);  
  39.             /* 
  40.              * 轮询监听客户端上注册事件的发生 
  41.              */  
  42.             while (true) {  
  43.                 selector.select();  
  44.                 Set<SelectionKey> keySet = selector.selectedKeys();  
  45.                 for(final SelectionKey key : keySet){  
  46.                     handle(key);  
  47.                 };  
  48.                 keySet.clear();  
  49.             }  
  50.         } catch (Exception e) {  
  51.             e.printStackTrace();  
  52.         }  
  53.     }  
  54.     public static void main(String[] args) throws IOException {  
  55.         NIOClient client = new NIOClient(7777);  
  56.     }  
  57.       
  58.     private void handle(SelectionKey selectionKey) throws IOException{  
  59.         if (selectionKey.isConnectable()) {  
  60.             /* 
  61.              * 连接建立事件,已成功连接至服务器 
  62.              */  
  63.             client = (SocketChannel) selectionKey.channel();  
  64.             if (client.isConnectionPending()) {  
  65.                 client.finishConnect();  
  66.                 System.out.println("connect success !");  
  67.                 sBuffer.clear();  
  68.                 sBuffer.put((new Date().toLocaleString()+" connected!").getBytes());  
  69.                 sBuffer.flip();  
  70.                 client.write(sBuffer);//发送信息至服务器  
  71.                 /* 原文来自站长网
  72.                  * 启动线程一直监听客户端输入,有信心输入则发往服务器端 
  73.                  * 因为输入流是阻塞的,所以单独线程监听 
  74.                  */  
  75.                 new Thread(){  
  76.                     @Override  
  77.                     public void run() {  
  78.                         while(true){  
  79.                             try {  
  80.                                 sBuffer.clear();  
  81.                                 InputStreamReader input = new InputStreamReader(System.in);  
  82.                                 BufferedReader br = new BufferedReader(input);  
  83.                                 sendText = br.readLine();  
  84.                                 /* 
  85.                                  * 未注册WRITE事件,因为大部分时间channel都是可以写的 
  86.                                  */  
  87.                                 sBuffer.put(sendText.getBytes());  
  88.                                 sBuffer.flip();  
  89.                                 client.write(sBuffer);  
  90.                             } catch (IOException e) {  
  91.                                 e.printStackTrace();  
  92.                                 break;  
  93.                             }  
  94.                       }  
  95.                     };  
  96.                 }.start();  
  97.             }  
  98.             //注册读事件  
  99.             client.register(selector, SelectionKey.OP_READ);  
  100.         } else if (selectionKey.isReadable()) {  
  101.             /* 
  102.              * 读事件触发 
  103.              * 有从服务器端发送过来的信息,读取输出到屏幕上后,继续注册读事件 
  104.              * 监听服务器端发送信息 
  105.              */  
  106.             client = (SocketChannel) selectionKey.channel();  
  107.             rBuffer.clear();  
  108.             count=client.read(rBuffer);  
  109.             if(count>0){  
  110.                 receiveText = new String( rBuffer.array(),0,count);  
  111.                 System.out.println(receiveText);  
  112.                 client = (SocketChannel) selectionKey.channel();  
  113.                 client.register(selector, SelectionKey.OP_READ);  
  114.             }  
  115.         }   
  116.     }  
  117. }  原文来自java教程网 http://www.software8.co/wzjs/java/   欢迎java爱好者前来投稿

posted on 2013-01-05 15:51 你爸是李刚 阅读(9109) 评论(3)  编辑  收藏

评论

# re: java nio SocketChannel 服务器端与多客户端 信息交互(聊天功能) 2016-01-20 22:48 Irving

selector.keys()应该是selector.selectedKeys()吧  回复  更多评论   

# re: java nio SocketChannel 服务器端与多客户端 信息交互(聊天功能) 2016-01-20 22:50 Irving

看错了sorry  回复  更多评论   

# re: java nio SocketChannel 服务器端与多客户端 信息交互(聊天功能) 2016-01-21 11:39 佛挡杀佛

gdsgsg  回复  更多评论   


只有注册用户登录后才能发表评论。


网站导航:
 
<2016年1月>
272829303112
3456789
10111213141516
17181920212223
24252627282930
31123456

导航

统计

常用链接

留言簿

随笔档案

文章档案

技术网站

行业网站

搜索

最新评论

阅读排行榜

评论排行榜

站长网 氟塑料离心泵 注塑机 液晶广告机