?? 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 + -