最近比较懒,好久没有更新博客了。这个代码早就写了,但是一直没有发出来,今天又更新了一下功能,发出来。算是我最近重新复习线程的一个总结吧。以前就看过java的多线程处理,但是一直有点迷迷糊糊的,不是很清楚,这次通过写这个程序,算是有了点头绪了。而且以前没有用过socket这个对象,也是初次接触,不错的东东,蛮有意思的。争取以后继续深化一下这方面。
程序分2部分,服务器端和客户端。服务器端负责信息的处理,如发送欢迎信息,帮助信息之类的,统一分发消息等。客户端呢,则是简单的接受来自服务端的消息,以及控制台的信息输入。
服务器端:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Date;
import java.util.Vector;
/**
* Lan Communication Server
*
* @author webkkk
* @version 1.0
*/
public class TestSocket {
private final int defalutPort = 6665;
TestSocketServerCenter serverCenter;
public TestSocket() {
try {
ServerSocket server = new ServerSocket(defalutPort);
serverCenter = new TestSocketServerCenter(server, this);
serverCenter.start();
TestSocketInfoCenter infoCenter = new TestSocketInfoCenter(this);
infoCenter.start();
} catch (IOException e) {
printMsg(e.getMessage());
}
}
/**
* @param args
*/
public static void main(String[] args) {
new TestSocket();
}
public void printMsg(String strInfo) {
System.err.println(String.valueOf(new Date()) + "->" + strInfo);
}
}
class TestSocketServerCenter extends Thread {
ServerSocket server;
TestSocket main;
Vector clientManager = new Vector();
Vector infoManager = new Vector();
int intClientCount = 0;
int intActivedSeq = 0;
public TestSocketServerCenter(ServerSocket server, TestSocket main) {
this.server = server;
this.main = main;
}
public void run() {
while (true) {
try {
Socket socket = server.accept();
TestSocketServer server = new TestSocketServer(socket, this, intClientCount);
server.start();
clientManager.add(server);
infoManager.add("User-" + intClientCount);
welcome(socket);
intClientCount++;
} catch (IOException e) {
main.printMsg("[TestSocketServerCenter]" + e.getMessage());
}
}
}
private void welcome(Socket socket) {
intActivedSeq = intClientCount;
allMessage("joined in");
StringBuffer sb = new StringBuffer("------------------------------\r\n");
sb.append("Welcome " + infoManager.get(intActivedSeq) + "\r\n");
sb.append("ps:You can use help command to learn about command.\r\n");
sb.append("------------------------------");
singleMessage(socket, sb.toString());
}
private void bye(int intSeq) {
intActivedSeq = intSeq;
allMessage("quited");
}
private void allMessage(String strMsg) {
String strSubMsg;
// broadcast to the all users
for (int i = 0; i < clientManager.size(); i++) {
Socket socket = ((TestSocketServer) clientManager.get(i)).socket;
strSubMsg = infoManager.get(intActivedSeq) + " has " + strMsg + ".";
singleMessage(socket, strSubMsg);
}
}
private void singleMessage(Socket socket, String strMsg) {
PrintWriter pw;
// the message for the new login user
try {
pw = new PrintWriter(socket.getOutputStream());
pw.println(strMsg);
pw.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
public void modifyInfo(int intSeq) {
bye(intSeq);
clientManager.remove(intSeq);
infoManager.remove(intSeq);
intClientCount--;
for (int i = 0; i < clientManager.size(); i++) {
((TestSocketServer) clientManager.get(i)).setIntSeq(i);
}
}
}
class TestSocketServer extends Thread {
TestSocketServerCenter center;
Socket socket;
BufferedReader br;
PrintWriter pw;
boolean exitFlg = true;
Vector arrMsg = new Vector();
public int intSeq;
boolean blnHidden = false;
public TestSocketServer(Socket socket, TestSocketServerCenter center, int intClientCount) {
this.socket = socket;
this.center = center;
this.intSeq = intClientCount;
}
public void run() {
try {
br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
pw = new PrintWriter(socket.getOutputStream());
String strMsg;
while (exitFlg) {
strMsg = br.readLine();
if (strMsg == null || "exit".equalsIgnoreCase(strMsg)
|| "quit".equalsIgnoreCase(strMsg)) {
exitFlg = false;
} else if ("help".equalsIgnoreCase(strMsg)) {
showTheHelpInfo();
} else if (strMsg.startsWith("rename")) {
String[] strName = strMsg.split(" ");
changeName(strName[1]);
} else if ("list".equalsIgnoreCase(strMsg)) {
list();
} else if ("listall".equalsIgnoreCase(strMsg)) {
listAll();
} else if ("off".equalsIgnoreCase(strMsg)) {
sethiddenFlg(true);
} else if ("on".equalsIgnoreCase(strMsg)){
sethiddenFlg(false);
} else if (!"".equals(strMsg)) {
saveMsg(strMsg);
}
}
} catch (IOException e) {
this.center.main.printMsg("[TestSocketServer]" + e.getMessage());
} finally {
// remove the closed socket from vector
center.modifyInfo(intSeq);
pw.close();
try {
br.close();
socket.close();
} catch (IOException e) {
this.center.main.printMsg("[TestSocketServer]" + e.getMessage());
}
}
}
/**
* save the input message
* @param strMsg
*/
private void saveMsg(String strMsg) {
arrMsg.add(strMsg);
}
/**
* output the message
* @param strInfo
*/
public void sendMsg(String strInfo) {
pw.println(strInfo);
pw.flush();
}
/**
* modify the nick name
* @param strNewName
*/
public void changeName(String strNewName) {
center.infoManager.set(intSeq, strNewName);
}
public void sethiddenFlg(boolean blnFlg) {
this.blnHidden = blnFlg;
}
/**
* show the online users
*
*/
public void list() {
pw.println("Online user:");
for (int i = 0; i < center.infoManager.size(); i++) {
if (!((TestSocketServer)center.clientManager.get(i)).blnHidden)
pw.println(center.infoManager.get(i));
}
pw.flush();
}
public void listAll() {
pw.println("Online user:");
boolean flg;
for (int i = 0; i < center.infoManager.size(); i++) {
flg = ((TestSocketServer)center.clientManager.get(i)).blnHidden;
pw.println(center.infoManager.get(i) + (flg ? " △" : ""));
}
pw.flush();
}
/**
* save the sequence of the vector
* @param intSeq
*/
public void setIntSeq(int intSeq) {
this.intSeq = intSeq;
}
/**
* show the operation menu
*
*/
private void showTheHelpInfo() {
pw.println("list:show the online user`s name.");
pw.println("rename:change your nickname.exam rename xxxxx");
pw.println("off:hidden your name from the online user.");
pw.println("on:show your name on the online user.");
pw.println("exit:quit from this system");
pw.flush();
}
}
class TestSocketInfoCenter extends Thread {
TestSocket main;
Vector clientManager;
TestSocketServer server;
Vector arrInfo = new Vector();
public TestSocketInfoCenter(TestSocket main) {
this.main = main;
}
public void run() {
while (true) {
clientManager = main.serverCenter.clientManager;
for (int i = 0; i < clientManager.size(); i++) {
arrInfo = ((TestSocketServer) clientManager.get(i)).arrMsg;
String strClientName = (String) main.serverCenter.infoManager.get(i);
sendToAll(arrInfo, strClientName);
}
try {
sleep(100);
} catch (Exception e) {
main.printMsg(e.getMessage());
}
}
}
private void sendToAll(Vector arrInfo, String strClientName) {
for (int i = 0; i < clientManager.size(); i++) {
server = (TestSocketServer) clientManager.get(i);
for (int j = 0; j < arrInfo.size(); j++) {
server.sendMsg(strClientName + "->" + String.valueOf(arrInfo.get(j)));
}
}
arrInfo.removeAllElements();
}
}
客户端:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
public class TestSocketClient {
private final String defaultServer = "172.16.34.227";
private final int defaultPort = 6665;
public boolean blnFlg = true;
public TestSocketClient() {
try {
Socket socket = new Socket(defaultServer, defaultPort);
clientInputThread input = new clientInputThread(socket, this);
input.start();
clientOutputThread output = new clientOutputThread(socket, this);
output.start();
} catch (UnknownHostException e) {
outputMsg(e.getMessage());
} catch (IOException e) {
outputMsg(e.getMessage());
}
}
/**
* @param args
*/
public static void main(String[] args) {
new TestSocketClient();
}
public void outputMsg(String strMsg) {
SimpleDateFormat sdft = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
Calendar rightNow = Calendar.getInstance();
System.out.println(sdft.format(rightNow.getTime()) + "->" + strMsg);
}
}
class clientInputThread extends Thread {
Socket socket;
BufferedReader br;
PrintWriter pw;
TestSocketClient client;
public clientInputThread(Socket socket, TestSocketClient client) {
this.socket = socket;
this.client = client;
}
public void run() {
br = new BufferedReader(new InputStreamReader(System.in));
String strMsg;
try {
pw = new PrintWriter(socket.getOutputStream());
} catch (IOException e) {
client.outputMsg(e.getMessage());
}
while (client.blnFlg) {
try {
strMsg = br.readLine();
if (!"".equals(strMsg)) {
pw.println(strMsg);
pw.flush();
if (strMsg.equalsIgnoreCase("exit") || strMsg.equalsIgnoreCase("quit")) {
client.blnFlg = false;
}
}
} catch (IOException e) {
client.outputMsg(e.getMessage());
}
}
}
}
class clientOutputThread extends Thread {
Socket socket;
TestSocketClient client;
BufferedReader br;
public clientOutputThread(Socket socket, TestSocketClient client) {
this.socket = socket;
this.client = client;
}
public void run() {
try {
br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String strMsg;
while (client.blnFlg) {
strMsg = br.readLine();
if (strMsg != null) {
System.out.println(strMsg);
}
}
} catch (IOException e) {
client.outputMsg(e.getMessage());
System.exit(0);
}
}
}