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

📄 chatserver.java

📁 JAVA 聊天室源码
💻 JAVA
字号:
package liaotshi2;

import java.awt.event.*;
import java.net.*;
import java.io.*;
import java.util.*;
import javax.swing.*;


//Code for the AppServer class
public class chatServer extends JApplet  implements Runnable, ActionListener {

	ServerSocket server;
	Socket fromClient;
	Thread serverThread;
	JButton b1, b2;
	JPanel panel;

	public chatServer()	 {
		panel = new JPanel();
		b1 = new JButton("启动服务器");
		b2 = new JButton("关闭服务器");
		panel.add(b1);
		panel.add(b2);
		b2.setVisible(false);
		b1.addActionListener(this);
		b2.addActionListener(this);
		this.getContentPane().add(panel);
	}
	
	public void startServer() {
		try {
			server = new ServerSocket(7894);
			serverThread = new Thread(this);
			System.out.println("Server started...");
			serverThread.start();
		} catch (Exception e) {
			System.out.println("Cannot start the thread " + e);
		}

	}
	
	public void stopServer() {
		if(server != null) {
			try {
				server.close();
				server = null;
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
		}
	}

	public void run() {
		try {
			while (true) {
				fromClient = server.accept();// 返回客户套接字
				Client c = new Client(fromClient);
				System.out.println("connectioned...");

			}
		} catch (Exception e) {
			System.out.println("Cannot listen to the client" + e);
		}
	}
	
	public void actionPerformed(ActionEvent e) {
		if(e.getSource() == b1) {
			/*JOptionPane.showMessageDialog(null, "不在聊00——22:00", "警告",
					JOptionPane.ERROR_MESSAGE);*/
			startServer();
			
			b1.setVisible(false);
			b2.setVisible(true);
		} else if(e.getSource() == b2) {
			stopServer();
			b1.setVisible(true);
			b2.setVisible(false);
		}
		
	}

	public static void main(String args[]) {
		new chatServer();
	}
}

class Client extends Thread {
	/*
	 * 为了让用户能够看见其他用户发送的信息,必须用向量来存储每个客户发送的信息, 及存储其套接字
	 */
	static Vector clients = new Vector(30);// 向量用来存储每个客户的套接字,即socket
	PrintStream ps;// 用来发送到套接字的类,即发送给客户端的类
	String name;
	// To store user name
	// String fromUser;
	Socket socket;
	BufferedReader fromClient;// 用来读取套接字的类,即从客户端读取信息的类

	public void send(StringBuffer msg) // 实现想客户端发送信息的方法
	{
		ps.println(msg); // 用打印流发送信息
		ps.flush();
	}

	public Client(Socket s) {
		socket = s;
		// Retrieving the clients stream
		try {
			clients.addElement(this);// 每一个客户登陆时就将其套接字存储进来

			fromClient = new BufferedReader(new InputStreamReader(socket
					.getInputStream())); // 存储特定客户socket的输入流接受s这个客户发送到服务器端的信息
			ps = new PrintStream(socket.getOutputStream()); // 存储特定客户socket的输出流发送服务器给s这个客户的信息
			/*
			 * String info=fromClient.readLine(); //读取接受来的信息 StringTokenizer
			 * stinfo=new StringTokenizer(info,":");
			 * //用StringTokenizer类来读取用":"分段字符 String head=stinfo.nextToken();
			 * //head用来存储类似于关键字的头信息 if(stinfo.hasMoreTokens())
			 * name=stinfo.nextToken(); notifyRoom();
			 */
		} catch (Exception e) {
			System.out.println("Cannot get the client stream" + e);
		}
		this.start();
	}

	public void run() // 线程运行方法
	{
		try {
			String info = fromClient.readLine(); // 读取接受来的信息
			StringTokenizer stinfo = new StringTokenizer(info, ":"); // 用StringTokenizer类来读取用":"分段字符
			String head = stinfo.nextToken(); // head用来存储类似于关键字的头信息
			if (stinfo.hasMoreTokens())
				name = stinfo.nextToken();// 获得客户的名字
			name = name.trim();// 去掉空格
			notifyRoom();// 调用发送在线用户列表给客户端的方法
			welcomeNew();// 调用欢迎客户登陆的方法
		} catch (Exception e2) {
		}

		while (true)// 循环一直监听客户短发送过来的内容
		{
			String line = null;
			try {
				line = fromClient.readLine(); // 读取客户端发来的数据流

			} catch (IOException e) {
				// System.out.println("Error"+e);
				disconnect();

				return;
			}

			/*
			 * if(socket==null) //客户已离开 { disconnect(); notifyRoom(); return; }
			 */
			/*
			 * 因为客户短发送过来内容很多,包括注册信息,公聊的内容,私聊的内容等等,
			 * 为了区分这些内容需要用StringTokenizer这个类来实现
			 */
			StringTokenizer st = new StringTokenizer(line, ":");// 将从客户端读取过来的内容进行分类
			String keyword = st.nextToken();

			if (keyword.equals("MSG")) // 如果关键字是MSG则是客户端发来的聊天信息
			{
				StringBuffer msg = new StringBuffer("MSG:"); // 在服务器端再重新建立一个字符缓冲
				String message = st.nextToken();
				msg.append(name + message);
				// msg.append(st.nextToken());
				sendClients(msg); // 再将某个客户发来的聊天信息发送到每个连接客户的聊天栏中
			}

			if (keyword.equals("PRIVATE")) // 如果客户端发送过来的是private,则发送私聊的内容回去
			{
				StringBuffer privateMsg = new StringBuffer("PRIVATE:");
				String clientName = st.nextToken();
				String receiver = st.nextToken();

				// if(st.hasMoreTokens())
				String pm = st.nextToken();
				String all = clientName + ":" + receiver + ":" + pm;
				privateMsg.append(all);
				sendClients(privateMsg);

			}
			/*
			 * else if(keyword.equals("QUIT")) //如果关键字是QUIT则是客户端发来断开连接的信息 {
			 * 
			 * disconnect(); //服务器断开与这个客户的连接 notifyRoom();
			 * //继续监听聊天室并刷新其他客户的聊天人名list }
			 */
		}
	}

	public synchronized void disconnect() // 实现断开单个客户的方法
	{

		try {

			clients.removeElement(this);
			notifyRoom();
			StringBuffer quit = new StringBuffer("QUIT:");
			quit.append(name);
			sendClients(quit);
			socket.close();
		} catch (Exception e1) {
		}

	}

	public synchronized void sendClients(StringBuffer msg) // 实现sendClients方法专用来向每个连接的客户端发送信息
	{
		for (int i = 0; i < clients.size(); i++)// 遍历向量,即将每一个客户套接字里面的内容返回给每一个客户端客户端
		{
			Client c = (Client) clients.elementAt(i);
			c.send(msg);
		}
	}

	public void notifyRoom() // 用来监视连接信息,不断刷新clients数组并刷新客户端用户列表信息
	{
		StringBuffer people = new StringBuffer("PEOPLE");
		// String welcome="欢迎"+name+"的大驾光临";
		for (int i = 0; i < clients.size(); i++) {
			Client c = (Client) clients.elementAt(i);
			people.append(":" + c.name);

		}
		sendClients(people); // 用sendClients方法向客户端发送信息
	}

	public void welcomeNew() // 用来发送欢迎信息的方法
	{
		StringBuffer welcome = new StringBuffer("WELCOME:");
		String textWelcome = "欢迎" + name + "的大驾光临";
		welcome.append(textWelcome);
		sendClients(welcome);
	}
}

⌨️ 快捷键说明

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