nio 聊天窗口

 服务器

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> users;
	
	//用户上线列表
	private Vector<String> userNames;
	
	public Server(int port)
	{
		isOpen = true;
		users = UsersData.dataUsers();
		userNames = new Vector<String>();
		init(port);
	}
	
	
	@Override
	public void run() 
	{
		try {
			while(isOpen)
			{
				//接收信息的数量
				int result = selector.select();
				if(result > 0)
				{
					for (Iterator<SelectionKey> 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<SelectionKey> 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<SelectionKey> 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 + "^" + writeContext.getText());
				writeContext.setText(null);
			}
		});
		
		//关闭按钮事件
		btnRes.addActionListener(new ActionListener() {	
			@Override
			public void actionPerformed(ActionEvent e) {
				isConntext = false;
				//发送关闭信息
				userBiz.sendToServer("exit_" + userName);
				System.exit(0);
			}
		});
		
		
		list.addListSelectionListener(new ListSelectionListener() {	
			@Override
			public void valueChanged(ListSelectionEvent e) {
				JOptionPane.showMessageDialog(null,list.getSelectedValue().toString());
			}
		});
		
		aFrame.add(btnSub);
		aFrame.add(btnRes);
		aFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}
	
	//界面显示
	public void show() throws IOException, ClassNotFoundException
	{
		init();
		aFrame.setVisible(true);
		userBiz.sendToServer("open");
	}
	
	class ctUsers extends Thread
	{
		public void run() 
		{
			while(isConntext)
			{
				//获取服务器传过的值
				Object obj = userBiz.sendToClient();
				
				//判断值是否有空
				if(obj != null)
				{
					
					if(obj.toString().indexOf("[") != -1 && obj.toString().lastIndexOf("]") != -1)
					{
						obj = obj.toString().substring(1, obj.toString().length()-1);
						String [] userNames = obj.toString().split(",");
						modle.removeAllElements();
						for (int i = 0; i < userNames.length; i++) {
							modle.addElement(userNames[i].trim());
						}
					}
					else
					{
						String str = readContext.getText() + obj.toString();
						readContext.setText(str);
					}
				}
			}
		}
	}
}

 

 客户端业务类

package com.ww.biz;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;


public class ClientServerBIz {
	
	private SocketChannel sc;
	public ClientServerBIz() throws IOException
	{
		sc = SocketChannel.open();
		sc.configureBlocking(false);
		sc.connect(new InetSocketAddress("localhost",8001));
	}

	//发送信息到服务器
	public void sendToServer(Object obj)
	{
		try {
			while(!sc.finishConnect())
			{}
			sc.write(ByteBuffer.wrap(obj.toString().getBytes()));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	//获取服务器信息传递信息到客户端
	public Object sendToClient()
	{
		ByteBuffer buffer = ByteBuffer.allocate(1024 * 1024);
		buffer.clear();
		StringBuffer sb = new StringBuffer();
		int count = 0;
		Object obj = null;
		try {
			//获取字节长度
			Thread.sleep(100);
			while ((count = sc.read(buffer)) > 0) {
				sb.append(new String(buffer.array(), 0, count));
            }
			if( sb.length() > 0 )
			{
				obj = sb.toString();
				if("close".equals(sb.toString()))
				{
					obj = null;
					sc.close();
					sc.socket().close();
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		return obj;
	}
}

 数据源

package com.ww.dao;

import java.util.ArrayList;
import java.util.List;

import com.ww.entity.Users;

public class UsersData {
	public static List<Users> dataUsers()
	{
		List<Users> users = new ArrayList<Users>();
		Users user1 = new Users("tiantian","123456");
		Users user2 = new Users("dongdong","123456");
		Users user3 = new Users("xiaoxiao","123456");
		Users user4 = new Users("mingming","123456");
		users.add(user1);
		users.add(user2);
		users.add(user3);
		users.add(user4);
		return users;
	}
}

 

实体

package com.ww.entity;

import java.io.Serializable;

public class Users implements Serializable{
	private String userName;
	private String userPass;
	public String getUserName() {
		return userName;
	}
	public void setUserName(String userName) {
		this.userName = userName;
	}
	public String getUserPass() {
		return userPass;
	}
	public void setUserPass(String userPass) {
		this.userPass = userPass;
	}
	public Users(String userName,String userPass)
	{
		this.userName = userName;
		this.userPass = userPass;
	}
}

 

各位大侠小弟有地方写的不好的地方请指点一二!

你可能感兴趣的:(DAO,thread,socket,swing,qq)