📄 chatserver.java
字号:
/* 范例名称:聊天室程序
* 源文件名称:ChatClient.java/ChatServer.java
* 要 点:
* 1. Java Socket编程
* 2. 多线程编程
* 3. 程序体系结构及设计思想
*/
import java.io.*;
import java.net.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Vector; //Vector 集合对于线程是安全的
public class ChatServer extends Frame implements WindowListener
{
TextArea display;
int num=1;
int port;
ServerSocket server;
BufferedReader input;
BufferedWriter output;
Vector<String> msgV; //消息集合,用到泛型
/*
*构造方法完成初始化工作
*/
public ChatServer(int port1)
{
super("聊天室正在运行中.....");
display=new TextArea(200,300);
this.add("Center",display);
addWindowListener(this);
setSize(300,400);
setVisible(true);
this.port=port1;
msgV=new Vector<String>(10); //指定向量集合初始容量
}
/**
*关闭窗口事件
*1.显示正在关闭chat server
*2.在消息队列msgV中加入"shutdown"字符串
*3.线程睡眠5001ms
*/
public void windowClosing(WindowEvent e)
{
display.append("服务器正在关闭中...\n");
display.append("通知聊天者...\n");
display.append("请等待中...");
msgV.add("shutdown"); // 消息集合中增加shutdown
try{Thread.sleep(5000);}
catch(Exception e2){}
dispose();
System.exit(0);
}
public void windowOpened(WindowEvent e)
{
}
public void windowActivated(WindowEvent e)
{
}
public void windowClosed(WindowEvent e)
{
}
public void windowDeactivated(WindowEvent e)
{
}
public void windowDeiconified(WindowEvent e)
{
}
public void windowIconified(WindowEvent e)
{
}
public void run()
{
try
{
server=new ServerSocket(port,3);
display.append("聊天服务器运行中...\n");
while(true) //让服务器线程一直运行
{
Socket clientSocket=server.accept();
clientConnection conn=new clientConnection(clientSocket,num,display,msgV); //为客户创建服务线程
display.append("第 "+(num++)+" 位聊天者\n");
}
}
catch(IOException e)
{
System.out.println("连接不成功!");
}
}
public static void main(String args[])
{
ChatServer chatServer=new ChatServer(7);
chatServer.run();
}
}
class clientConnection extends Thread //服务线程
{
String name;
Socket cSocket;
BufferedReader input;
PrintWriter output;
int num;
TextArea display; //服务器端显示区域
Vector<String> msgV;
public clientConnection(Socket cSocket,int num,TextArea display,Vector<String> msgV)
{
try{
input = new BufferedReader(new InputStreamReader(cSocket.getInputStream())); //封装服务器端的输出流(对应于客户端输入流)
output = new PrintWriter(cSocket.getOutputStream(),true);//封装服务器端的输出流(对应于客户端输入流)
this.name=input.readLine();
}
catch(IOException e)
{
e.printStackTrace();
}
this.cSocket = cSocket;
this.num=num; //聊天者人数
this.display=display;
this.msgV=msgV;
this.start(); //启动自己的线程对象
}
synchronized public void run() //用到同步,防止多个聊天者同时修改display,msgV
{
String line;
try
{
while(true)
{
line = input.readLine();
if(line.equals("End")) //读取到客户端发来的消息,"End"代表聊天者离开了
{
display.append("系统消息 : "+name+" 离开了 !\n");
break;
}
if(line.equals("PleaseSendALL")) //读取到客户端发来的消息,"PleaseSendALL"代表聊天者发消息
{
if(!msgV.isEmpty()) //消息集合有元素
{
int ii=msgV.size() ; //消息集合的大小
output.println(ii);
for(int i=0;i<msgV.size();i++)
{
output.println(msgV.get(i)); //取出所有消息集合中,将消息内容都发到客户端
}
//output.println("end");
}
else
output.println("0");
}
else
{
line=name+" 说:"+ line+"\n"; //加入了换行符
display.append(line); // 将客户端的消息添加到服务端的面板上
msgV.add(line); // 将客户端的消息添加到消息集合中
}
}
}
catch(IOException ex)
{
ex.printStackTrace();
}
finally //用到fianlly块释放资源
{
try
{
cSocket.close(); //关闭套接字
}
catch(IOException ex2)
{
ex2.printStackTrace();
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -