新聞中心
這里有您想知道的互聯(lián)網營銷解決方案
JavaNIO聊天窗口實例
一、服務器

- package com.ww.server;
- import java.io.IOException;
- import java.net.InetSocketAddress;
- 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.text.SimpleDateFormat;
- import java.util.Date;
- import java.util.Iterator;
- import java.util.List;
- import java.util.Vector;
- import com.ww.dao.UsersData;
- import com.ww.entity.Users;
- public class Server implements Runnable{
- //選擇器
- private Selector selector;
- //選擇key
- private SelectionKey sscKey;
- //服務器開關
- private boolean isOpen;
- //用戶集合
- private List
users; - //用戶上線列表
- private Vector
userNames; - public Server(int port)
- {
- isOpen = true;
- users = UsersData.dataUsers();
- userNames = new Vector
(); - init(port);
- }
- @Override
- public void run()
- {
- try {
- while(isOpen)
- {
- //接收信息的數(shù)量
- int result = selector.select();
- if(result > 0)
- {
- for (Iterator
iterator = selector.selectedKeys().iterator(); iterator.hasNext();) - {
- SelectionKey key = (SelectionKey) iterator.next();
- iterator.remove();
- //判斷是否是接收狀態(tài)
- if(key.isAcceptable())
- {
- System.out.println("==========客戶端開啟==========");
- getConn(key);
- }
- //判斷是否是讀取狀態(tài)
- else if(key.isReadable())
- {
- System.out.println("=============讀取=============");
- ReadMsg(key);
- }
- //判斷是否是寫入狀態(tài)
- else if(key.isWritable())
- {
- System.out.println("=============寫入=============");
- WriteMsg(key);
- }
- }
- }
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- //初始化服務器
- private void init(int port)
- {
- try {
- //開啟選擇器
- selector = Selector.open();
- //開啟ServerSocket
- ServerSocketChannel ssc = ServerSocketChannel.open();
- //設置非阻塞模式
- ssc.configureBlocking(false);
- //設置端口
- ssc.socket().bind(new InetSocketAddress(port));
- //注冊到選擇器里并設置為接收狀態(tài)
- sscKey = ssc.register(selector,SelectionKey.OP_ACCEPT);
- System.out.println("==========開啟服務器==========");
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- //獲取連接
- private void getConn(SelectionKey key) throws IOException
- {
- //獲取ServerSocket
- ServerSocketChannel ssc = (ServerSocketChannel)key.channel();
- //設置Socket
- SocketChannel sc = ssc.accept();
- //設置非阻塞模式
- sc.configureBlocking(false);
- //注冊到選擇器里并設置為讀取狀態(tài)
- sc.register(selector, SelectionKey.OP_READ);
- }
- //讀取信息
- private void ReadMsg(SelectionKey key) throws IOException
- {
- //獲取到Socket
- SocketChannel sc = (SocketChannel)key.channel();
- ByteBuffer buffer = ByteBuffer.allocate(1024 * 1024);
- buffer.clear();
- StringBuffer sb = new StringBuffer();
- //獲取字節(jié)長度
- int count = sc.read(buffer);
- if( count > 0 )
- {
- buffer.flip();
- sb.append(new String(buffer.array(), 0, count));
- }
- Object obj = (Object)sb.toString();
- if(obj.toString().indexOf("-")!= -1)
- {
- //獲取用戶名
- String userName = obj.toString().substring(0, obj.toString().indexOf("-"));
- //獲取用戶密碼
- String userPass = obj.toString().substring(obj.toString().indexOf("-") + 1);
- boolean isTrue = false;
- //判斷用戶是否存在
- for (int i = 0; i < users.size(); i++) {
- if(users.get(i).getUserName().equals(userName) && users.get(i).getUserPass().equals(userPass))
- {
- System.out.println("========" + userName + "登錄成功========");
- isTrue = true;
- userNames.addElement(userName);
- KeyAttach(key,"true");
- break;
- }
- isTrue = false;
- }
- //用戶不存在
- if(!isTrue)
- {
- System.out.println("========" + userName + "登錄失敗========");
- KeyAttach(key,"false");
- }
- }
- else if(obj.toString().equals("open"))
- {
- System.out.println("=========開啟聊天窗口=========");
- //給都有的用戶返回用戶列表
- AllKeysAttach(key,userNames);
- }
- else if( obj.toString().indexOf("exit_") != -1 )
- {
- String userName = obj.toString().substring(5);
- userNames.removeElement(userName);
- System.out.println("========" + userName + "退出窗體========");
- KeyAttach(key,"close");
- OtherKeysAttach(key,userNames);
- }
- else
- {
- //獲取用戶名
- String userName = obj.toString().substring(0,obj.toString().indexOf("^"));
- //獲取信息
- String mess = obj.toString().substring(obj.toString().indexOf("^")+1);
- //獲取發(fā)信時間
- SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
- String dateTime = dateFormat.format(new Date());
- //設置信息
- String mss = userName + " " + dateTime + "\n" + mess + "\n";
- //給都有的用戶返回聊天信息
- AllKeysAttach(key,mss);
- }
- }
- //所有client改成寫入狀態(tài)
- private void AllKeysAttach(SelectionKey key,Object obj)
- {
- for (Iterator
iterator = key.selector().keys().iterator(); iterator.hasNext();) - {
- SelectionKey selKey = (SelectionKey) iterator.next();
- //判斷不是Server key;
- if( selKey != sscKey )
- {
- selKey.attach(obj);
- //把其他client改成可寫狀態(tài)
- selKey.interestOps( selKey.interestOps() | SelectionKey.OP_WRITE );
- }
- }
- }
- //把其他客戶改成寫入狀態(tài)
- private void OtherKeysAttach(SelectionKey key,Object obj)
- {
- for (Iterator
iterator = key.selector().keys().iterator(); iterator.hasNext();) - {
- SelectionKey selKey = (SelectionKey) iterator.next();
- //判斷不是本生client key和Server key;
- if( selKey != sscKey && selKey != key )
- {
- selKey.attach(obj);
- //把其他client改成可寫狀態(tài)
- selKey.interestOps( selKey.interestOps() | SelectionKey.OP_WRITE );
- }
- }
- }
- //自身改成寫入狀態(tài)
- private void KeyAttach(SelectionKey key,Object obj)
- {
- key.attach(obj);
- key.interestOps(SelectionKey.OP_WRITE);
- }
- //發(fā)送信息
- private void WriteMsg(SelectionKey key) throws IOException
- {
- //獲取到Socket
- SocketChannel sc = (SocketChannel)key.channel();
- //獲取附屬值
- Object obj = key.attachment();
- //把附屬值設為空
- key.attach("");
- //發(fā)送信息
- sc.write(ByteBuffer.wrap(obj.toString().getBytes()));
- if(obj.toString().equals("close") || obj.toString().equals("false"))
- {
- key.cancel();
- sc.socket().close();
- sc.close();
- System.out.println("==========客戶端關閉==========");
- return;
- }
- //設置為讀取狀態(tài)
- key.interestOps(SelectionKey.OP_READ);
- }
- public static void main(String[] args)
- {
- Server server = new Server(8001);
- new Thread(server).start();
- }
- }
二、客戶端界面
1.登錄界面
- package com.ww.frame;
- import java.awt.Color;
- import java.awt.Font;
- import java.awt.event.ActionEvent;
- import java.awt.event.ActionListener;
- import java.awt.event.WindowAdapter;
- import java.awt.event.WindowEvent;
- import java.io.IOException;
- import javax.swing.JButton;
- import javax.swing.JFrame;
- import javax.swing.JLabel;
- import javax.swing.JTextField;
- import com.ww.biz.ClientServerBIz;
- import com.ww.frame.ChatFrame;
- public class LoginFrame {
- private JLabel
- lblTitle = new JLabel("山寨版QQ"),
- lblUserName = new JLabel("用戶名:"),
- lblPassword = new JLabel("密 碼:");
- private JTextField
- txtUserName = new JTextField(15),
- txtPassword = new JTextField(15);
- private JButton
- btnSub = new JButton("提交"),
- btnRes = new JButton("取消");
- private JFrame
- aFrame = new JFrame("登錄山寨QQ");
- private ClientServerBIz clientBiz;
- public LoginFrame()
- {
- into();
- }
- private void into()
- {
- aFrame.setLayout(null);
- aFrame.setBounds(300, 300, 200, 180);
- lblTitle.setBounds(45, 10, 100, 40);
- lblTitle.setForeground(new Color(120, 120, 120));
- lblTitle.setFont(new Font("山寨版QQ", 1, 20));
- aFrame.add(lblTitle);
- lblUserName.setBounds(10, 50, 80, 20);
- aFrame.add(lblUserName);
- lblPassword.setBounds(10, 80, 80, 20);
- aFrame.add(lblPassword);
- txtUserName.setBounds(65, 50, 120, 20);
- aFrame.add(txtUserName);
- txtPassword.setBounds(65, 80, 120, 20);
- aFrame.add(txtPassword);
- btnSub.setBounds(10, 110, 80, 25);
- aFrame.add(btnSub);
- btnRes.setBounds(100, 110, 80, 25);
- aFrame.add(btnRes);
- btnSub.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- String userInfo = txtUserName.getText() + "-" + txtPassword.getText();
- try {
- clientBiz = new ClientServerBIz();
- clientBiz.sendToServer(userInfo);
- Object obj = clientBiz.sendToClient();
- System.out.println(obj.toString());
- if (Boolean.parseBoolean(obj.toString()))
- {
- ChatFrame cf = new ChatFrame(clientBiz,txtUserName.getText());
- cf.show();
- aFrame.setVisible(false);
- }
- else
- {
- System.out.println("用戶不存在或密碼錯誤!");
- }
- } catch (IOException e1) {
- e1.printStackTrace();
- } catch (ClassNotFoundException e1) {
- e1.printStackTrace();
- }
- }
- });
- btnRes.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- System.exit(0);
- }
- });
- aFrame.addWindowListener(new WindowAdapter() {
- @Override
- public void windowClosing(WindowEvent e) {
- System.exit(0);
- }
- });
- }
- public void show()
- {
- aFrame.setVisible(true);
- }
- public static void main(String[] args) {
- LoginFrame login = new LoginFrame();
- login.show();
- }
- }
2.聊天界面
- package com.ww.frame;
- import java.awt.event.ActionEvent;
- import java.awt.event.ActionListener;
- import java.awt.event.WindowAdapter;
- import java.awt.event.WindowEvent;
- import java.io.IOException;
- import javax.swing.DefaultListModel;
- import javax.swing.JButton;
- import javax.swing.JFrame;
- import javax.swing.JList;
- import javax.swing.JOptionPane;
- import javax.swing.JTextArea;
- import javax.swing.event.ListSelectionEvent;
- import javax.swing.event.ListSelectionListener;
- import com.ww.biz.ClientServerBIz;
- public class ChatFrame {
- //文本框
- private JTextArea
- readContext = new JTextArea(18,30),//顯示信息
- writeContext = new JTextArea(6,30);//發(fā)送信息
- //列表框
- private DefaultListModel modle = new DefaultListModel();//列表模型
- private JList list = new JList(modle);//列表
- //按鈕
- private JButton
- btnSub = new JButton("提交"),//提交按鈕
- btnRes = new JButton("取消");//取消按鈕
- //窗體界面
- private JFrame aFrame = new JFrame("ChatFrame");
- //用戶名
- private String userName;
- //Client業(yè)務類
- private ClientServerBIz userBiz;
- //設置線程是否運行
- private boolean isConntext = false;
- //構造方法
- public ChatFrame(ClientServerBIz clientBiz,String userName)
- {
- //獲取用戶名
- this.userName = userName;
- userBiz = clientBiz;
- //開啟線程
- isConntext = true;
- new Thread(new ctUsers()).start();
- }
- //初始化界面
- private void init() throws IOException, ClassNotFoundException
- {
- aFrame.setLayout(null);
- aFrame.setTitle(userName+" 聊天窗口");
- aFrame.setSize(500, 500);
- aFrame.setLocation(400, 200);
- readContext.setBounds(10, 10, 320, 285);
- readContext.setEditable(false);
- writeContext.setBounds(10, 305, 320, 100);
- list.setBounds(340, 10, 140, 445);
- aFrame.add(readContext);
- aFrame.add(writeContext);
- aFrame.add(list);
- btnSub.setBounds(150, 415, 80, 30);
- btnRes.setBounds(250, 415, 80, 30);
- //frame的關閉按鈕事件
- aFrame.addWindowListener(new WindowAdapter() {
- @Override
- public void windowClosing(WindowEvent e) {
- isConntext = false;
- //發(fā)送關閉信息
- userBiz.sendToServer("exit_" + userName);
- System.exit(0);
- }
- });
- //提交按鈕事件
- btnSub.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- //發(fā)送信息
- userBiz.sendToServer(userName + "^"
新聞標題:JavaNIO聊天窗口實例
網站網址:http://www.dlmjj.cn/article/coophpo.html


咨詢
建站咨詢
