⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 server.java

📁 简单的聊天程序
💻 JAVA
字号:
import java.io.*;
import java.net.*;
import java.sql.*;
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;



public class Server {
	private JFrame f;
	private JTextField portF;
	private int port;
	private boolean isRunning = false;
	private JLabel personsLab;
	private Connection con;
	/*封装了与各用户的连接!*/
	private HashMap<String,MySocket> user;
	private Socket currentSocket;
	private HashMap<String,ClientInfo> userInfo;
	private ClientInfo currentUserInfo;
	/**
	 * 服务器和当前服务的客户的通信
	 */
	private ObjectInputStream input;
	private ObjectOutputStream output;
	public Server(){
		init();
		buildGUI();
	}
	private void init(){
		/**SQL server 2000
		QQClient数据库,建立Client_Tab
		密码位cat,测试时候需要更改
		*/
		
		if(this.loadDBDriver("QQClient", "sa", "cat")){
			this.user = new HashMap<String, MySocket>();
			this.userInfo = new HashMap<String,ClientInfo>();
		}else{
			System.exit(0);
		}
	}
	/**
	 * 为了能够方便的设置服务器的端口
	 * 显示在线的人数而设计了简单的用户界面
	 */
	private void buildGUI(){
		this.f = new JFrame("QQ服务器");
		JLabel portLab = new JLabel("端口号: ");
		portF = new JTextField(20);
		/*默认端口号*/
		portF.setText("9999");
		JLabel oneLinePersonLab = new JLabel("在线人数: ");
		personsLab = new JLabel("0");
		final JButton cfmB = new JButton("确定");
		JPanel buttonP = new JPanel();
		buttonP.setLayout(new FlowLayout(FlowLayout.CENTER));
		buttonP.add(cfmB);
		cfmB.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){

				/*
				 *save useful info 
				 */
				preServe(cfmB);
				serve();
			}
		});
		Container c = f.getContentPane();
		GridBagLayout gb = new GridBagLayout();
		GridBagConstraints gbc = new GridBagConstraints();
		c.setLayout(gb);
		MyUtilities.addGCmp(c, portLab, gb, gbc, 0,0,1,1,1,1);
		MyUtilities.addGCmp(c, portF, gb, gbc, 1,0,1,1,1,1);
		MyUtilities.addGCmp(c, oneLinePersonLab, gb, gbc, 0,1,1,1,1,1);
		MyUtilities.addGCmp(c, personsLab, gb, gbc, 1,1,1,1,1,1);
		MyUtilities.addGCmp(c, buttonP, gb, gbc, 0,2,2,1,1,1);
		this.f.setIconImage(new ImageIcon("Img/85.gif").getImage());
		this.f.addWindowListener(new WindowAdapter(){
			public void windowClosing(WindowEvent e){
				isRunning = false;
				notifyAllUserExit();
				System.exit(0);
			}
		});
		this.f.setSize(400,200);
		this.f.setResizable(false);
		this.f.setVisible(true);
	}
	private void notifyAllUserExit(){

		this.user.clear();
	}
	private boolean loadDBDriver(String DBName,String user,String pw)
	{
		String url = "jdbc:microsoft:sqlserver://localhost:1433;DatabaseName="+DBName;
		try {
			Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver");
			this.con = DriverManager.getConnection(url,user,pw);
			return true;
		} catch (Exception e){
			e.printStackTrace();
			JOptionPane.showMessageDialog(null,
							"加载数据库时候出错!","连接错误",JOptionPane.ERROR_MESSAGE);
		}
		return false;
	}
	private void preServe(JButton b){
		b.setVisible(false);
		port = Integer.parseInt(portF.getText());
		portF.setEditable(false);
		Font f = new Font("黑体",Font.BOLD,30);
		this.personsLab.setFont(f);
		isRunning = true;
	}
	private void serve(){
		//接收用户连接
		new Thread(new Runnable(){
			public void run(){
				connectClient();
			}
		}).start();
		//用于接收用户退出的申请
		
	}
	//用于接收用户登录的线程
	private void connectClient(){
		try{
			ServerSocket s = new ServerSocket(this.port);
			while(this.isRunning){
				Socket sock = s.accept();
				this.currentSocket = sock;
				check();
			}
		}catch(Exception e)
		{}
	}
	private void check(){
		try{
			this.output = new ObjectOutputStream(
					this.currentSocket.getOutputStream());
			this.input = new ObjectInputStream(
					this.currentSocket.getInputStream());
			Message msg = ((Message)this.input.readObject());
			String sysMsg = msg.sysMsg;
			if(sysMsg.equals("登录")){
				dealLogin(msg.msg);
			}else if(sysMsg.equals("申请")){
				String number = null;
				try{
					number  = dealRequest(msg.msg);
				}catch(SQLException e)
				{
					e.printStackTrace();
				}
				//注册成功
				if(number != null){
					this.output.writeObject(new Message("注册成功",number));
				}else{
					this.output.writeObject(new Message("注册失败",""));
				}
				this.currentSocket.close();
			}
			else if(sysMsg.equals("下线")){
				this.currentSocket.close();
				dealUserQuit(msg.msg);
			}
		}catch(Exception e)
		{}
	}
	private void dealUserQuit(String qqNumber){
		this.user.remove(qqNumber);
		this.userInfo.remove(qqNumber);
		this.personsLab.setText(String.valueOf(this.user.size()));
		this.personsLab.repaint();
		/*更新用户中的在线列表*/
		Collection<String> coll = this.user.keySet();
		java.util.Iterator<String> ite = coll.iterator();
		while(ite.hasNext())
		{
			String key = ite.next();
			MySocket s = this.user.get(key);
			try {
				s.output.writeObject(new Message("有人下线",qqNumber));
			} catch (IOException e)
			{}
		}
	}
	/**
	 *检查登录是否合法,如果合法记录它的用户某些信息,便于传给List 
	 */
	private boolean isValidClient(String num,String pas){
		boolean isValid = false;
		try {
			PreparedStatement ps = con.prepareStatement(
			"SELECT Password,Age,Name,Sex,Nickname,Email,IconName,MySign FROM Client_Tab WHERE Number=?");
			ps.setString(1,num);
			ResultSet rs = ps.executeQuery();
			//如果没有判断rs.next()将出错
			if(rs.next()){
				isValid = (pas.equals(rs.getString("Password")));
				//记录用户信息
				if(isValid){
					ClientInfo info = new ClientInfo();
					info.number = num;
					info.age = rs.getInt("Age");
					info.iconName = rs.getString("IconName");
					info.nickName = rs.getString("Nickname");
					info.mySign = rs.getString("MySign");
					info.sex = rs.getString("Sex");
					info.name = rs.getString("Name");
					info.email = rs.getString("Email");
					info.ip = this.currentSocket.getInetAddress().getHostAddress();
					this.currentUserInfo = info;
					this.userInfo.put(info.number,this.currentUserInfo);
				}
			}
			else
				isValid = false;
		}catch(Exception e)
		{}
		return isValid;
	}
	private void dealLogin(String info)throws Exception{
		StringTokenizer st = new StringTokenizer(info);
		String ip = (String)st.nextElement();
		String num = (String)st.nextElement();
		String pas = (String)st.nextElement();
		if(isValidClient(num,pas)&& !this.user.containsKey(num)){
			this.output.writeObject(new Message("valid",""));
			/*保存连接*/
			this.user.put(num, new MySocket(this.currentSocket,this.output));
			/*更新在现的人数*/
			this.personsLab.setText(String.valueOf(this.user.size()));
			this.personsLab.repaint();
			/* 向已经登录的OnlineFrm发送所有的在线列表信息*/
			this.sendOnLineList(num);

		}
		//不合法的登录,断开连接,移除暂存的连接
		else{
			this.output.writeObject(new Message("Invalid",""));
			this.currentSocket.close();
		}
	}
	private void sendOnLineList(String currentNum)throws Exception{

		/*向新登录的人发送所有的在线人员*/
		Collection<ClientInfo> infoValueColl = this.userInfo.values();
		java.util.Iterator<ClientInfo> iteInfo = infoValueColl.iterator();
		while(iteInfo.hasNext()){
			this.output.writeObject(iteInfo.next());
		}
		/*向已经在线的人发送新增的人员信息*/
		Collection<String> coll = this.user.keySet();
		java.util.Iterator<String> ite = coll.iterator();
		while(ite.hasNext())
		{
			String key = ite.next();
			if(!currentNum.equals(key)){
				MySocket s = this.user.get(key);
				s.output.writeObject(this.currentUserInfo);
			}
		}
	}
	private String createNumber(){
		Statement st;
		String number = null;
		try {
			st = con.createStatement();
			ResultSet rs = st.executeQuery("SELECT Number FROM Client_Tab");
			//如果没有判断rs.next()将出错
			while(rs.next()){
				if(rs.isLast()){
					number = rs.getString("Number");
				}
			}
			System.exit(0);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		number = String.valueOf(Integer.valueOf(number)+1);
		System.out.println(number);
		return number;
	}
	/**
	 * 处理用户申请号码的线程工作方法
	 */
	private String dealRequest(String info)throws SQLException {
		String number;	//create a number
		number = createNumber();
		StringTokenizer st = new StringTokenizer(info,"&");
		String sex = st.nextToken();
		String nickname = st.nextToken();
		String email = st.nextToken();
		String name = st.nextToken();
		String age = st.nextToken();
		String password = st.nextToken();
		String iconName = st.nextToken();
		String sign = st.nextToken();
		String sqlAppend = "INSERT INTO Client_Tab" +
		"(Number,Password,Name,Age,Sex,Nickname,Email,IconName,MySign)" +
		"VALUES(?,?,?,?,?,?,?,?,?)";
		PreparedStatement ps = con.prepareStatement(sqlAppend);
		ps.setString(1,number);
		ps.setString(2,password);
		ps.setString(3,name);
		ps.setInt(4,Integer.parseInt(age));
		ps.setString(5,sex);
		ps.setString(6,nickname);
		ps.setString(7,email);
		ps.setString(8,iconName);
		ps.setString(9,sign);

		ps.executeUpdate();
		//关闭ps
		ps.close();
		return number;
	}
	
	
	public static void main(String[] args){
		new Server();
	}


}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -