📄 server.java
字号:
import java.awt.*;
import java.awt.event.*;
import java.net.*;
import java.io.*;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Calendar;
public class Server extends Frame implements ActionListener{
private boolean serving = false;
private Color bg = new Color(176, 196, 227);
private String rightNow;
private InetAddress svrAddress;
private ServerSocket server;
private ServerThread st;
private Hashtable ht; // 记录 String userName -> DataOutPutStream out
private Hashtable ht_s; // 记录 String userName -> Socket connection
private Label svrIP = new Label("Server IP:");
private TextField showSvrIP = new TextField();
private Label svrPort = new Label("Server port:");
private TextField getSvrPort = new TextField("8888");
private Button enter = new Button("Start");
private TextArea output = new TextArea();
private Label user = new Label("User (0)");
private List list = new List();
// 响应关闭按钮的内部类
private class WindowCloser extends WindowAdapter
{
public void windowClosing(WindowEvent we)
{
System.exit(0);
}
}
// 布局设置方法,在构造方法里面调用
private void setup()
{
Panel top = new Panel();
top.setLayout(new FlowLayout());
top.add(svrIP);
svrIP.setBackground(bg);
top.add(showSvrIP);
showSvrIP.setBackground(bg);
top.add(svrPort);
svrPort.setBackground(bg);
top.add(getSvrPort);
getSvrPort.setBackground(bg);
top.add(enter);
enter.setBackground(bg);
Panel east = new Panel();
east.setLayout(new BorderLayout());
east.add("North", user);
user.setBackground(bg);
east.add("Center", list);
list.setBackground(bg);
setLayout(new BorderLayout());
add("North", top);
top.setBackground(bg);
add("East", east);
east.setBackground(bg);
add("Center", output);
output.setBackground(bg);
setBackground(bg);
}
// 构造方法
public Server()throws UnknownHostException, IOException
{
super("Chat Room Server");
serving = false;
svrAddress = InetAddress.getLocalHost();
byte[] ip = svrAddress.getAddress();
showSvrIP.setText((ip[0]&0xFF)+"."+(ip[1]&0xFF)+"."
+(ip[2]&0xFF)+"."+(ip[3]&0xFF));
showSvrIP.setEditable(false);
output.setEditable(false);
enter.addActionListener(this);
addWindowListener(new WindowCloser());
setup();
pack();
setSize(500, 400);
show();
}
// 用于接收客户消息的线程类
private class ServerThreadSingle extends Thread{
public Socket connection;
private DataInputStream in;
private DataOutputStream out;
private boolean login;
private String userName;
public ServerThreadSingle(Socket _connection){
try{
connection = _connection;
in = new DataInputStream(connection.getInputStream());
out = new DataOutputStream(connection.getOutputStream());
login = false;
userName = new String("");
start();
}catch(IOException ioe){
output.append("Error: "+ioe);
}
}
public void run(){
try{
String line = new String("Q");
while(!login){
if(!serving) break;
line = in.readUTF();
if(line.charAt(0) == 'L'){
userName = line.substring(2);
if(userName.length() == 0){
out.writeUTF("R"); //refused
break;
}
// 判断是否已存在该用户名
for(Enumeration e = ht.keys(); e.hasMoreElements();){
String str = (String)(e.nextElement());
if(str.equalsIgnoreCase(userName)){
out.writeUTF("R"); //refused
return;
}
}
// 向登陆的用户发送当前在线用户列表
login = true;
list.add(userName);
user.setText("User ("+list.getItemCount()+")");
String[] str = list.getItems();
line = "A "; //accepted
for (int i = 0; i < str.length; i ++){
line += (str [i] + " ");
}
out.writeUTF(line);
line = "L "+userName;
rightNow = Calendar.getInstance().getTime().toLocaleString();
output.append(rightNow+"\n"+userName+" log in.\n\n");
// 向在线用户(不包括当前客户)发送消息
for(Enumeration e = ht.elements(); e.hasMoreElements();){
DataOutputStream out = (DataOutputStream)(e.nextElement());
out.writeUTF(line);
}
ht.put(userName, out); // 将登录的客户加入名单
ht_s.put(userName, connection);
}
}
while(login){
line = in.readUTF();
if(!serving) break;
if(line.charAt(0) == 'Q'){
out.writeUTF("Q");
login = false;
ht.remove(userName); // 将退出登录的客户从名单中剔除
ht_s.remove(userName);
list.remove(userName);
user.setText("User ("+list.getItemCount()+")");
line = "Q "+userName;
}
else{
line = userName+" said:\n"+line.substring(2);
}
rightNow = Calendar.getInstance().getTime().toLocaleString();
output.append(rightNow+"\n"+(line.charAt(0)=='Q'?userName+" log out.":line)+"\n\n");
// 向所有客户发送消息
for(Enumeration e = ht.elements(); e.hasMoreElements();){
DataOutputStream out = (DataOutputStream)(e.nextElement());
out.writeUTF(line);
}
}
in.close();
out.close();
connection.close();
}catch(SocketException se){
ht.remove(userName);
ht_s.remove(connection);
list.remove(userName);
output.append("Connection to "+userName+" closed\n");
}catch(IOException ioe){
if(!(ioe instanceof EOFException)){
output.append("Error: "+ioe+"\n\n");
}
}
}
}
// 用于接受客户连接请求的线程类
private class ServerThread extends Thread{
private boolean running;
public ServerThread()
{
start();
}
public void run()
{
try{
while(serving){
Socket connection = server.accept();
ServerThreadSingle handler
= new ServerThreadSingle(connection);
}
}catch(SocketException se){
rightNow = Calendar.getInstance().getTime().toLocaleString();
output.append(rightNow+"\nServing stoped.\n\n");
}catch(IOException ioe){
output.append("Error: "+ioe+"\n\n");
}
}
}
// 消息处理方法
public void actionPerformed(ActionEvent event)
{
if(event.getSource() == enter)
{
if(serving){
try{
for(Enumeration e = ht.elements(); e.hasMoreElements();){
DataOutputStream out = (DataOutputStream)(e.nextElement());
out.writeUTF("Q");
}
serving = false;
ht.clear();
ht_s.clear();
list.clear();
user.setText("User (0)");
server.close();
enter.setLabel("Start");
}catch(SocketException se){
rightNow = Calendar.getInstance().getTime().toLocaleString();
output.append(rightNow+"\nServing stoped.\n\n");
}catch(IOException ioe){
output.append("Error: "+ioe+"\n\n");
}
}
else{
try{
server = new ServerSocket(Integer.parseInt(getSvrPort.getText()));
rightNow = Calendar.getInstance().getTime().toLocaleString();
output.append(rightNow+"\nServing started.\n\n");
enter.setLabel("Stop");
ht = new Hashtable();
ht_s = new Hashtable();
st = new ServerThread();
serving = true;
}catch(IOException ioe){
output.append("Error: "+ioe+"\n\n");
}
}
}
}
// 主方法
public static void main(String args [])throws UnknownHostException, IOException
{
Server s = new Server();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -