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) {
		}
	}
}

  

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM