java socket 一个服务器对应多个客户端,可以互相发送消息

 

直接上代码,这是网上找的demo,然后自己根据需求做了一定的修改。代码可以直接运行

服务器端:

package socket;

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.LinkedList;
import java.util.List;
import java.util.Scanner;

public class Server extends ServerSocket {

	private static final int SERVER_PORT = 7777;

	public static boolean isPrint = false;// 是否输出消息标志
	private static List user_list = new ArrayList();// 登录用户集合
	private static List<ServerThread> thread_list = new ArrayList<ServerThread>();// 服务器已启用线程集合
	public static LinkedList<String> message_list = new LinkedList<String>();// 存放消息队列

	/**
	 * 创建服务端Socket,创建向客户端发送消息线程,监听客户端请求并处理
	 */
	public Server() throws IOException {
		super(SERVER_PORT);// 创建ServerSocket
		new PrintOutThread();// 创建向客户端发送消息线程
		new ListennerSocket();//创建监听客户端连接请求线程
	}
	/**
	 * 监听客户端连接请求线程
	 * @author zhang
	 * @date 2014-3-28-上午11:21:01
	 *
	 */
	class ListennerSocket extends Thread{
		public ListennerSocket() {
			start();
		}
		@Override
		public void run() {
			try {
				while (true) {// 监听客户端请求,启个线程处理
					Socket socket = accept();
					new ServerThread(socket);
				}
			} catch (Exception e) {
			} finally {
				try {
					close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

	/**
	 * 监听是否有输出消息请求线程类,向客户端发送消息
	 */
	class PrintOutThread extends Thread {

		public PrintOutThread() {
			start();
		}

		@Override
		public void run() {
			while (true) {
				if (isPrint) {// 将缓存在队列中的消息按顺序发送到各客户端,并从队列中清除。
					String message = message_list.getFirst();
					for (ServerThread thread : thread_list) {
						thread.sendMessage(message);
					}
					message_list.removeFirst();
					isPrint = message_list.size() > 0 ? true : false;
				}
			}
		}
	}

	/**
	 * 服务器线程类
	 */
	class ServerThread extends Thread {
		private Socket client;
		private PrintWriter out;
		private BufferedReader in;
		private String name;

		public ServerThread(Socket s) throws IOException {
			client = s;
			out = new PrintWriter(client.getOutputStream(), true);
			in = new BufferedReader(new InputStreamReader(
					client.getInputStream()));
//			in.readLine();
			out.println("成功连上聊天室,请输入你的名字:");
			start();
		}

		@Override
		public void run() {
			try {
				int flag = 0;
				String line = in.readLine();
				while (!"bye".equals(line)) {
					// 查看在线用户列表
					if ("showuser".equals(line)) {
						out.println(this.listOnlineUsers());
						line = in.readLine();
					}
					// 第一次进入,保存名字
					if (flag++ == 0) {
						name = line;
						user_list.add(name);
						thread_list.add(this);
						out.println(name + "你好,可以开始聊天了...");
						this.pushMessage("Client<" + name + ">进入聊天室...");
					} else {
						this.pushMessage("Client<" + name + "> say : " + line);
					}
					line = in.readLine();
				}
				out.println("byeClient");
			} catch (Exception e) {
				e.printStackTrace();
			} finally {// 用户退出聊天室
				try {
					client.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
				thread_list.remove(this);
				user_list.remove(name);
				pushMessage("Client<" + name + ">退出了聊天室");
			}
		}

		// 放入消息队列末尾,准备发送给客户端
		public void pushMessage(String msg) {
			message_list.addLast(msg);
			isPrint = true;
		}

		// 向客户端发送一条消息
		private void sendMessage(String msg) {
			out.println(msg);
		}

		// 统计在线用户列表
		private String listOnlineUsers() {
			String s = "--- 在线用户列表 ---\015\012";
			for (int i = 0; i < user_list.size(); i++) {
				s += "[" + user_list.get(i) + "]\015\012";
			}
			s += "--------------------";
			return s;
		}
	}

	public static void main(String[] args) throws IOException {
		new Server();// 启动服务端
		while(true){
			Scanner scanner = new Scanner(System.in);
			System.out.println("请输入发送给客户端的消息:");
			String string = scanner.nextLine();
			message_list.addLast(string);
			isPrint = true;
			
		}
	}
}

  

客户端:

package socket;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;

public class Client extends Socket {

	private static final String SERVER_IP = "192.168.21.178";
	private static final int SERVER_PORT = 7777;

	private Socket client;
	private PrintWriter out;
	private BufferedReader in;

	/**
	 * 与服务器连接,并输入发送消息
	 */
	public Client() throws Exception {
		super(SERVER_IP, SERVER_PORT);
		client = this;
		out = new PrintWriter(this.getOutputStream(), true);
		in = new BufferedReader(new InputStreamReader(this.getInputStream()));
		new readLineThread();

		while (true) {
			in = new BufferedReader(new InputStreamReader(System.in));
			String input = in.readLine();
			out.println(input);
		}
	}

	/**
	 * 用于监听服务器端向客户端发送消息线程类
	 */
	class readLineThread extends Thread {

		private BufferedReader buff;

		public readLineThread() {
			try {
				buff = new BufferedReader(new InputStreamReader(
						client.getInputStream()));
				start();
			} catch (Exception e) {
			}
		}

		@Override
		public void run() {
			try {
				while (true) {
					String result = buff.readLine();
					if ("byeClient".equals(result)) {// 客户端申请退出,服务端返回确认退出
						break;
					} else {// 输出服务端发送消息
						System.out.println(result);
					}
				}
				in.close();
				out.close();
				client.close();
			} catch (Exception e) {
			}
		}
	}

	public static void main(String[] args) {
		try {
			new Client();// 启动客户端
		} catch (Exception e) {
		}
	}
}

  

 

 

posted @ 2014-05-06 15:10  火光闪耀  阅读(6149)  评论(1编辑  收藏  举报