最近比较懒,好久没有更新博客了。这个代码早就写了,但是一直没有发出来,今天又更新了一下功能,发出来。算是我最近重新复习线程的一个总结吧。以前就看过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);
		}
	}
}