簡易聊天室的實現。

一個簡單的消息羣裏的聊天室功能,雖然功能不強大,主要是爲了給初學者梳理梳理一下思路。希望能夠幫到有需要的人,大家一同共同學習,互相幫助。’

package mysocket;
import java.io.BufferedWriter;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;
/**
 * 客戶端
 * @author DELL
 *
 */
public class Client {
	/*
	 * Socket 套接字
	 * 封裝了TCP協議連接和通訊的細節,使用它與遠端計算檢疫連接後可以通過兩條流來實現
	 * 相互的數據交換
	 */
	private Socket socket;
	//主方法
	public static void main(String[] args) {
		Client client = new Client();
		client.start();
	}
	//構造方法,初始化程序
	public Client() {
		/*
		 * 實例化Socket
		 * 實例Socket需要傳入兩個參數
		 * Socket(String host, int port)
		 * 1:服務端計算機地址信息(IP)
		 * 2:服務端程序申請的服務端口
		 * 
		 * 實例化過程就是與服務端建立連接的過程,
		 * 若指定的IP地址與端口無效時,這裏實例化
		 * 就會拋出異常。因此我們在實例化的同時要處理
		 * 異常。
		 * 
		 */
		try {
			System.out.println("正在連接服務端...");
			socket = new Socket("localhost",8088);
			System.out.println("服務端連接成功!");
		} catch (Exception e) {
		}
	}
	//運行程序的方法
	public void start() {
		/*
		 * 這裏執行與服務端進行消息交互的方法。
		 * 如果希望向服務端發送消息我們需要通過Socket
		 * OutputStream  getOnputStream()
		 * 方法獲取輸出流
		 */
		try {
			/*
			 * 串聯一個流連接,提升效率
			 */
			OutputStream out = socket.getOutputStream();
			OutputStreamWriter osw = new OutputStreamWriter(out,"UTF-8");
			BufferedWriter bw = new BufferedWriter(osw);
			PrintWriter pw = new PrintWriter(bw,true);//此處注意參數true,若不添加此方法我們需要頻繁調用flush方法來保證消息的及時性。
			Scanner scan = new Scanner(System.in);
			while(true) {
				String line = scan.nextLine();
				pw.println(line);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
package mysocket;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
/**
 * 服務端
 * @author DELL
 *
 */
public class Server {
	/*
	 * java.net.ServerSocket
	 * 運行在服務端的ServerSocket主要有兩個作用
	 * 1:向系統申請服務端口,客戶端就是通過這個端口與服務端建立連接的
	 * 2:監聽服務端口,一旦客戶端通過該端口連接則馬上會實例化一個
	 * Socket與之反應。服務端就可以通過這個Socket與客戶端進行交互了。
	 * 
	 * 如果把Socket比喻爲電話,那麼ServerSocket可以想象爲是總機。
	 */
	private ServerSocket server;
	public static void main(String[] args) {
		Server server = new Server();
		server.start();
	}
	//構造方法,初始化程序
	public Server() {
		try {
			/*
			 * 實例化ServerSocket的同時要制定服務端口。
			 * 當該端口已經被系統其它程序所使用時,會拋出地址被佔用的異常。
			 * 因此我們也需要使用異常處理機制處理一下。
			 */
			System.out.println("正在啓動服務端...");
			server = new ServerSocket(8088);
			System.out.println("服務端啓動完畢!");
		} catch (IOException e) {
		}
	}
	public void start() {
		while(true) {
			/*
			 * ServerSocket提供的方法:
			 * Socket accept();
			 * 該方法是一個阻塞方法,執行後服務端開始監聽服務端口,知道一個客戶端連接爲止,
			 * 這時該方法會返回一個Socket實例,通過該實例即可以與客戶端進行通訊了。
			 * 每次調用該方法都會導致服務端阻塞,等待一個客戶端的連接。
			 */
			try {
				System.out.println("正在等待客戶端連接...");
				Socket socket = server.accept();
				//此時在等待一個窗口爲8088的客戶端連接,我們要實現羣聊效果,因此需要使用到多線程。
				MyRunnable client = new MyRunnable(socket);
				Thread thread = new Thread(client);
				thread.start();
			} catch (Exception e) {
				// TODO: handle exception
			}
		}
		
	}
}
class MyRunnable implements Runnable{
	private Socket socket;
	String host;
	public MyRunnable(Socket socket) {
		this.socket = socket;
		/*
		 * getInetAddress()返回對象包含遠程計算機的IP地址
		 * InetAddress.getHostAddress()返回對象與該地址的文本表示。
		 */
		InetAddress address = socket.getInetAddress();
		host = address.getHostAddress();
		System.out.println("IP:"+host+"連接成功!");
	}
	public void run() {
		try {
			//在這裏我也同樣通過Socket提供的方法實現與客戶端的交互
			InputStream in = socket.getInputStream();
			InputStreamReader isr = new InputStreamReader(in,"utf-8");
			BufferedReader br = new BufferedReader(isr);
			String str = null;
			/*
			 * br.readLine()讀取客戶端發送過來的一行字符串的操作中
			 * 當客戶端斷開連接時,客戶端系統不同
			 * 這裏的表現也不同
			 * 通常windows的客戶端斷開時,readLine方法會直接拋出異常
			 * linux的客戶端斷開連接時,readLine方法的返回值通常爲null
			 */
			while((str = br.readLine())!=null) {
				System.out.println("IP:"+host+"說:"+str);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章