一、服务器

- 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)
 - {
 - //接收信息的数量
 - int result = selector.select();
 - if(result > 0)
 - {
 - for (Iterator
 iterator = selector.selectedKeys().iterator(); iterator.hasNext();) - {
 - SelectionKey key = (SelectionKey) iterator.next();
 - iterator.remove();
 - //判断是否是接收状态
 - if(key.isAcceptable())
 - {
 - System.out.println("==========客户端开启==========");
 - getConn(key);
 - }
 - //判断是否是读取状态
 - else if(key.isReadable())
 - {
 - System.out.println("=============读取=============");
 - ReadMsg(key);
 - }
 - //判断是否是写入状态
 - 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));
 - //注册到选择器里并设置为接收状态
 - 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);
 - //注册到选择器里并设置为读取状态
 - 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();
 - //获取字节长度
 - 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);
 - //获取发信时间
 - 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改成写入状态
 - 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改成可写状态
 - selKey.interestOps( selKey.interestOps() | SelectionKey.OP_WRITE );
 - }
 - }
 - }
 - //把其他客户改成写入状态
 - 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改成可写状态
 - selKey.interestOps( selKey.interestOps() | SelectionKey.OP_WRITE );
 - }
 - }
 - }
 - //自身改成写入状态
 - private void KeyAttach(SelectionKey key,Object obj)
 - {
 - key.attach(obj);
 - key.interestOps(SelectionKey.OP_WRITE);
 - }
 - //发送信息
 - private void WriteMsg(SelectionKey key) throws IOException
 - {
 - //获取到Socket
 - SocketChannel sc = (SocketChannel)key.channel();
 - //获取附属值
 - Object obj = key.attachment();
 - //把附属值设为空
 - key.attach("");
 - //发送信息
 - 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;
 - }
 - //设置为读取状态
 - 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);//发送信息
 - //列表框
 - 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业务类
 - 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;
 - //发送关闭信息
 - userBiz.sendToServer("exit_" + userName);
 - System.exit(0);
 - }
 - });
 - //提交按钮事件
 - btnSub.addActionListener(new ActionListener() {
 - @Override
 - public void actionPerformed(ActionEvent e) {
 - //发送信息
 - userBiz.sendToServer(userName + "^"
 本文名称:JavaNIO聊天窗口实例
文章分享:http://www.csdahua.cn/qtweb/news8/317358.html网站建设、网络推广公司-快上网,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 快上网