📄 chatserver.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 + -