?? clientconnection.java
字號:
import java.net.*;
import java.io.*;
import java.util.*;
/**
* ClientConnection 是ServerConnection的鏡像。它為每個客戶創建一個
* 連接。它的工作是管理與客戶之間的I/O操作
**/
class ClientConnection implements Runnable {
private Socket sock;
private BufferedReader in;
private OutputStream out;
private String host;
private Server server;
private static final String CRLF = "\r\n";
private String name = null; // for humans
private String id;
private boolean busy = false;
/** 構造函數保存服務器的引用變量,套接字和唯一的ID。最后創建并
* 啟動一個新線程處理連接*/
public ClientConnection(Server srv, Socket s, int i) {
try {
server = srv;
sock = s;
in = new BufferedReader(new InputStreamReader(s.getInputStream()));
out = s.getOutputStream();
host = s.getInetAddress().getHostName();
id = "" + i;
write("id " + id + CRLF);
new Thread(this).start();
} catch (IOException e) {
System.out.println("failed ClientConnection " + e);
}
}
/** 重載toString()函數,來清楚的表示一個連接記錄 */
public String toString() {
return id + " " + host + " " + name;
}
// 下面的getHost(), getId(), isBusy(), setBusy()將host,id和
// busy包裝在公用方法中允許只讀訪問
public String getHost() {
return host;
}
public String getId() {
return id;
}
public boolean isBusy() {
return busy;
}
public void setBusy(boolean b) {
busy = b;
}
/** 如果客戶顯式退出或在讀套接字時捕獲到一個異常則調用本函數*/
public void close() {
server.kill(this);
try {
sock.close(); // closes in and out too.
} catch (IOException e) { }
}
/** 將字符串寫入流,使用getBytes()方法來將它轉換成一個字節數組 */
public void write(String s) {
byte buf[];
buf = s.getBytes();
try {
out.write(buf, 0, buf.length);
} catch (IOException e) {
close();
}
}
private String readline() {
try {
return in.readLine();
} catch (IOException e) {
return null;
}
}
// 這部分和ServerConnection類中的對應部分類似,解析另一方的消息。
static private final int NAME = 1;
static private final int QUIT = 2;
static private final int TO = 3;
static private final int DELETE = 4;
static private Hashtable keys = new Hashtable();
static private String keystrings[] = {
"", "name", "quit", "to", "delete"
};
static {
for (int i = 0; i < keystrings.length; i++)
keys.put(keystrings[i], new Integer(i));
}
private int lookup(String s) {
Integer i = (Integer) keys.get(s);
return i == null ? -1 : i.intValue();
}
/** 本方法循環管理所有與客戶通信的消息 */
public void run() {
String s;
StringTokenizer st;
while ((s = readline()) != null) {
st = new StringTokenizer(s);
String keyword = st.nextToken();
switch (lookup(keyword)) {
default:
System.out.println("bogus keyword: " + keyword + "\r");
break;
case NAME:
name = st.nextToken() +
(st.hasMoreTokens() ? " " + st.nextToken(CRLF) : "");
System.out.println("[" + new Date() + "] " + this + "\r");
server.set(id, this);
break;
case QUIT:
close();
return;
case TO:
String dest = st.nextToken();
String body = st.nextToken(CRLF);
server.sendto(dest, body);
break;
case DELETE:
busy = true;
server.delete(id);
break;
}
}
close();
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -