JavaNIO聊天窗口实例

一、服务器

 
 
 
  1. package com.ww.server;
  2. import java.io.IOException;
  3. import java.net.InetSocketAddress;
  4. import java.nio.ByteBuffer;
  5. import java.nio.channels.SelectionKey;
  6. import java.nio.channels.Selector;
  7. import java.nio.channels.ServerSocketChannel;
  8. import java.nio.channels.SocketChannel;
  9. import java.text.SimpleDateFormat;
  10. import java.util.Date;
  11. import java.util.Iterator;
  12. import java.util.List;
  13. import java.util.Vector;
  14. import com.ww.dao.UsersData;
  15. import com.ww.entity.Users;
  16. public class Server implements Runnable{
  17.     
  18.     //选择器
  19.     private Selector selector;
  20.     
  21.     //选择key
  22.     private SelectionKey sscKey;
  23.     
  24.     //服务器开关
  25.     private boolean isOpen;
  26.     
  27.     //用户集合
  28.     private List users;
  29.     
  30.     //用户上线列表
  31.     private Vector userNames;
  32.     
  33.     public Server(int port)
  34.     {
  35.         isOpen = true;
  36.         users = UsersData.dataUsers();
  37.         userNames = new Vector();
  38.         init(port);
  39.     }
  40.     
  41.     
  42.     @Override
  43.     public void run() 
  44.     {
  45.         try {
  46.             while(isOpen)
  47.             {
  48.                 //接收信息的数量
  49.                 int result = selector.select();
  50.                 if(result > 0)
  51.                 {
  52.                     for (Iterator iterator = selector.selectedKeys().iterator(); iterator.hasNext();) 
  53.                     {
  54.                         SelectionKey key = (SelectionKey) iterator.next();
  55.                         iterator.remove();
  56.                         //判断是否是接收状态
  57.                         if(key.isAcceptable())
  58.                         {
  59.                             System.out.println("==========客户端开启==========");
  60.                             getConn(key);
  61.                         }
  62.                         //判断是否是读取状态
  63.                         else if(key.isReadable())
  64.                         {
  65.                             System.out.println("=============读取=============");
  66.                             ReadMsg(key);
  67.                         }
  68.                         //判断是否是写入状态
  69.                         else if(key.isWritable())
  70.                         {
  71.                             System.out.println("=============写入=============");
  72.                             WriteMsg(key);
  73.                         }
  74.                         
  75.                     }
  76.                 }
  77.                 
  78.             }
  79.         } catch (IOException e) {
  80.             e.printStackTrace();
  81.         }
  82.     }
  83.     //初始化服务器
  84.     private void init(int port)
  85.     {
  86.         try {
  87.             //开启选择器
  88.             selector = Selector.open();
  89.             //开启ServerSocket
  90.             ServerSocketChannel ssc = ServerSocketChannel.open();
  91.             //设置非阻塞模式
  92.             ssc.configureBlocking(false);
  93.             //设置端口
  94.             ssc.socket().bind(new InetSocketAddress(port));
  95.             //注册到选择器里并设置为接收状态
  96.             sscKey = ssc.register(selector,SelectionKey.OP_ACCEPT);
  97.             System.out.println("==========开启服务器==========");
  98.             
  99.         } catch (IOException e) {
  100.             e.printStackTrace();
  101.         }
  102.     }
  103.     
  104.     //获取连接
  105.     private void getConn(SelectionKey key) throws IOException
  106.     {
  107.         //获取ServerSocket
  108.         ServerSocketChannel ssc = (ServerSocketChannel)key.channel();
  109.         //设置Socket
  110.         SocketChannel sc = ssc.accept();
  111.         //设置非阻塞模式
  112.         sc.configureBlocking(false);
  113.         //注册到选择器里并设置为读取状态
  114.         sc.register(selector, SelectionKey.OP_READ);
  115.     }
  116.     
  117.     //读取信息
  118.     private void ReadMsg(SelectionKey key) throws IOException
  119.     {
  120.         //获取到Socket
  121.         SocketChannel sc = (SocketChannel)key.channel();
  122.         ByteBuffer buffer = ByteBuffer.allocate(1024 * 1024);
  123.         buffer.clear();
  124.         StringBuffer sb = new StringBuffer();
  125.         //获取字节长度
  126.         int count = sc.read(buffer);
  127.         if( count > 0 )
  128.         {
  129.             buffer.flip();
  130.             sb.append(new String(buffer.array(), 0, count));
  131.         }
  132.         Object obj = (Object)sb.toString();
  133.         if(obj.toString().indexOf("-")!= -1)
  134.         {
  135.             //获取用户名
  136.             String userName = obj.toString().substring(0, obj.toString().indexOf("-"));
  137.             //获取用户密码
  138.             String userPass = obj.toString().substring(obj.toString().indexOf("-") + 1);
  139.             
  140.             boolean isTrue = false;
  141.             //判断用户是否存在
  142.             for (int i = 0; i < users.size(); i++) {
  143.                 if(users.get(i).getUserName().equals(userName) && users.get(i).getUserPass().equals(userPass))
  144.                 {
  145.                     System.out.println("========" + userName + "登录成功========");
  146.                     isTrue = true;
  147.                     userNames.addElement(userName);
  148.                     KeyAttach(key,"true");
  149.                     break;
  150.                 }
  151.                 isTrue = false;
  152.             }
  153.             
  154.             //用户不存在
  155.             if(!isTrue)
  156.             {
  157.                 System.out.println("========" + userName + "登录失败========");
  158.                 KeyAttach(key,"false");
  159.             }
  160.         }
  161.         else if(obj.toString().equals("open"))
  162.         {
  163.             System.out.println("=========开启聊天窗口=========");
  164.             //给都有的用户返回用户列表
  165.             AllKeysAttach(key,userNames);
  166.         }
  167.         else if( obj.toString().indexOf("exit_") != -1 )
  168.         {
  169.             String userName = obj.toString().substring(5);
  170.             userNames.removeElement(userName);
  171.             System.out.println("========" + userName + "退出窗体========");
  172.             KeyAttach(key,"close");
  173.             OtherKeysAttach(key,userNames);
  174.         }
  175.         else
  176.         {
  177.             //获取用户名
  178.             String userName = obj.toString().substring(0,obj.toString().indexOf("^"));
  179.             //获取信息
  180.             String mess = obj.toString().substring(obj.toString().indexOf("^")+1);
  181.             //获取发信时间
  182.             SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
  183.             String dateTime = dateFormat.format(new Date());
  184.             //设置信息
  185.             String mss = userName + " " + dateTime + "\n" + mess + "\n";
  186.             //给都有的用户返回聊天信息
  187.             AllKeysAttach(key,mss);
  188.         }
  189.         
  190.     }
  191.     
  192.     //所有client改成写入状态
  193.     private void AllKeysAttach(SelectionKey key,Object obj)
  194.     {
  195.         for (Iterator iterator = key.selector().keys().iterator(); iterator.hasNext();) 
  196.         {
  197.             SelectionKey selKey = (SelectionKey) iterator.next();
  198.             //判断不是Server key;
  199.             if( selKey != sscKey )
  200.             {
  201.                 selKey.attach(obj);
  202.                 //把其他client改成可写状态
  203.                 selKey.interestOps( selKey.interestOps() | SelectionKey.OP_WRITE );
  204.             }
  205.         }
  206.     }
  207.     
  208.     //把其他客户改成写入状态
  209.     private void OtherKeysAttach(SelectionKey key,Object obj)
  210.     {
  211.         for (Iterator iterator = key.selector().keys().iterator(); iterator.hasNext();) 
  212.         {
  213.             SelectionKey selKey = (SelectionKey) iterator.next();
  214.             //判断不是本生client key和Server key;
  215.             if( selKey != sscKey && selKey != key )
  216.             {
  217.                 selKey.attach(obj);
  218.                 //把其他client改成可写状态
  219.                 selKey.interestOps( selKey.interestOps() | SelectionKey.OP_WRITE );
  220.             }
  221.         }
  222.     }
  223.     
  224.     //自身改成写入状态
  225.     private void KeyAttach(SelectionKey key,Object obj)
  226.     {
  227.         key.attach(obj);
  228.         key.interestOps(SelectionKey.OP_WRITE);
  229.     }
  230.     
  231.     //发送信息
  232.     private void WriteMsg(SelectionKey key) throws IOException
  233.     {
  234.         //获取到Socket
  235.         SocketChannel sc = (SocketChannel)key.channel();
  236.         //获取附属值
  237.         Object obj = key.attachment();
  238.         //把附属值设为空
  239.         key.attach("");
  240.         //发送信息
  241.         sc.write(ByteBuffer.wrap(obj.toString().getBytes()));
  242.         if(obj.toString().equals("close") || obj.toString().equals("false"))
  243.         {
  244.             key.cancel();
  245.             sc.socket().close();
  246.             sc.close();
  247.             System.out.println("==========客户端关闭==========");
  248.             return;
  249.         }
  250.         //设置为读取状态
  251.         key.interestOps(SelectionKey.OP_READ);
  252.     }
  253.     
  254.     public static void main(String[] args) 
  255.     {   
  256.         Server server = new Server(8001);
  257.         new Thread(server).start();
  258.     }
  259. }

二、客户端界面

1.登录界面

 
 
 
  1. package com.ww.frame;
  2. import java.awt.Color;
  3. import java.awt.Font;
  4. import java.awt.event.ActionEvent;
  5. import java.awt.event.ActionListener;
  6. import java.awt.event.WindowAdapter;
  7. import java.awt.event.WindowEvent;
  8. import java.io.IOException;
  9. import javax.swing.JButton;
  10. import javax.swing.JFrame;
  11. import javax.swing.JLabel;
  12. import javax.swing.JTextField;
  13. import com.ww.biz.ClientServerBIz;
  14. import com.ww.frame.ChatFrame;
  15. public class LoginFrame {
  16.     
  17.     private JLabel 
  18.         lblTitle = new JLabel("山寨版QQ"),
  19.         lblUserName = new JLabel("用户名:"),
  20.         lblPassword = new JLabel("密     码:");
  21.     
  22.     private JTextField 
  23.         txtUserName = new JTextField(15),
  24.         txtPassword = new JTextField(15);
  25.     
  26.     private JButton
  27.         btnSub = new JButton("提交"),
  28.         btnRes = new JButton("取消");
  29.     
  30.     private JFrame
  31.         aFrame = new JFrame("登录山寨QQ");
  32.     
  33.     private ClientServerBIz clientBiz;
  34.     public LoginFrame()
  35.     {
  36.         into();
  37.     }
  38.     
  39.     private void into()
  40.     {
  41.         aFrame.setLayout(null);
  42.         aFrame.setBounds(300, 300, 200, 180);
  43.         lblTitle.setBounds(45, 10, 100, 40);
  44.         lblTitle.setForeground(new Color(120, 120, 120));
  45.         lblTitle.setFont(new Font("山寨版QQ", 1, 20));
  46.         aFrame.add(lblTitle);
  47.         lblUserName.setBounds(10, 50, 80, 20);
  48.         aFrame.add(lblUserName);
  49.         lblPassword.setBounds(10, 80, 80, 20);
  50.         aFrame.add(lblPassword);
  51.         txtUserName.setBounds(65, 50, 120, 20);
  52.         aFrame.add(txtUserName);
  53.         txtPassword.setBounds(65, 80, 120, 20);
  54.         aFrame.add(txtPassword);
  55.         btnSub.setBounds(10, 110, 80, 25);
  56.         aFrame.add(btnSub);
  57.         btnRes.setBounds(100, 110, 80, 25);
  58.         aFrame.add(btnRes);
  59.         
  60.         btnSub.addActionListener(new ActionListener() {
  61.             @Override
  62.             public void actionPerformed(ActionEvent e) {
  63.                 String userInfo = txtUserName.getText() + "-" + txtPassword.getText();
  64.                 try {
  65.                     clientBiz = new ClientServerBIz();
  66.                     clientBiz.sendToServer(userInfo);
  67.                     Object obj = clientBiz.sendToClient();
  68.                     System.out.println(obj.toString());
  69.                     if (Boolean.parseBoolean(obj.toString()))
  70.                     {
  71.                         ChatFrame cf = new ChatFrame(clientBiz,txtUserName.getText());
  72.                         cf.show();
  73.                         aFrame.setVisible(false);
  74.                     }
  75.                     else
  76.                     {
  77.                         System.out.println("用户不存在或密码错误!");
  78.                     }
  79.                 } catch (IOException e1) {
  80.                     e1.printStackTrace();
  81.                 } catch (ClassNotFoundException e1) {
  82.                     e1.printStackTrace();
  83.                 }
  84.             }
  85.         });
  86.         
  87.         btnRes.addActionListener(new ActionListener() {
  88.             @Override
  89.             public void actionPerformed(ActionEvent e) {
  90.                 System.exit(0);
  91.             }
  92.         });
  93.         
  94.         aFrame.addWindowListener(new WindowAdapter() {
  95.             @Override
  96.             public void windowClosing(WindowEvent e) {
  97.                 System.exit(0);
  98.             }   
  99.         });
  100.     }
  101.     
  102.     public void show()
  103.     {
  104.         aFrame.setVisible(true);
  105.     } 
  106.     
  107.     public static void main(String[] args) {
  108.         LoginFrame login = new LoginFrame();
  109.         login.show();
  110.     }
  111. }

2.聊天界面

 
 
 
  1. package com.ww.frame;
  2. import java.awt.event.ActionEvent;
  3. import java.awt.event.ActionListener;
  4. import java.awt.event.WindowAdapter;
  5. import java.awt.event.WindowEvent;
  6. import java.io.IOException;
  7. import javax.swing.DefaultListModel;
  8. import javax.swing.JButton;
  9. import javax.swing.JFrame;
  10. import javax.swing.JList;
  11. import javax.swing.JOptionPane;
  12. import javax.swing.JTextArea;
  13. import javax.swing.event.ListSelectionEvent;
  14. import javax.swing.event.ListSelectionListener;
  15. import com.ww.biz.ClientServerBIz;
  16. public class ChatFrame {
  17.     
  18.     //文本框
  19.     private JTextArea
  20.         readContext = new JTextArea(18,30),//显示信息
  21.         writeContext = new JTextArea(6,30);//发送信息
  22.     
  23.     //列表框
  24.     private DefaultListModel modle = new DefaultListModel();//列表模型
  25.     private JList list = new JList(modle);//列表
  26.     
  27.     //按钮
  28.     private JButton 
  29.         btnSub = new JButton("提交"),//提交按钮
  30.         btnRes = new JButton("取消");//取消按钮
  31.     
  32.     //窗体界面
  33.     private JFrame aFrame = new JFrame("ChatFrame");
  34.     
  35.     //用户名
  36.     private String userName;
  37.     
  38.     //Client业务类
  39.     private ClientServerBIz userBiz;
  40.     
  41.     //设置线程是否运行
  42.     private boolean isConntext = false;
  43.     
  44.     //构造方法
  45.     public ChatFrame(ClientServerBIz clientBiz,String userName)
  46.     {
  47.         //获取用户名
  48.         this.userName = userName;
  49.         userBiz = clientBiz;
  50.         //开启线程
  51.         isConntext = true;
  52.         new Thread(new ctUsers()).start();  
  53.     }
  54.     
  55.     //初始化界面
  56.     private void init() throws IOException, ClassNotFoundException
  57.     {
  58.         aFrame.setLayout(null);
  59.         aFrame.setTitle(userName+" 聊天窗口");
  60.         aFrame.setSize(500, 500);
  61.         aFrame.setLocation(400, 200);
  62.         readContext.setBounds(10, 10, 320, 285);
  63.         readContext.setEditable(false);
  64.         writeContext.setBounds(10, 305, 320, 100);
  65.         list.setBounds(340, 10, 140, 445);
  66.         aFrame.add(readContext);
  67.         aFrame.add(writeContext);
  68.         aFrame.add(list);
  69.         btnSub.setBounds(150, 415, 80, 30);
  70.         btnRes.setBounds(250, 415, 80, 30);
  71.         
  72.         //frame的关闭按钮事件
  73.         aFrame.addWindowListener(new WindowAdapter() {
  74.             @Override
  75.             public void windowClosing(WindowEvent e) {
  76.                 isConntext = false;
  77.                 //发送关闭信息
  78.                 userBiz.sendToServer("exit_" + userName);
  79.                 System.exit(0);
  80.             }
  81.         });
  82.         //提交按钮事件
  83.         btnSub.addActionListener(new ActionListener() {
  84.             @Override
  85.             public void actionPerformed(ActionEvent e) {
  86.                 //发送信息
  87.                 userBiz.sendToServer(userName + "^" 分享标题:JavaNIO聊天窗口实例
    路径分享:http://www.shufengxianlan.com/qtweb/news8/317358.html

    网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等

    广告

    声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联