1. 程式人生 > >在java網路程式設計中實現伺服器和客戶端一對一的聊天

在java網路程式設計中實現伺服器和客戶端一對一的聊天

如果有多個客戶端接入,都可以傳送訊息給伺服器,但伺服器只和最後一個客戶聊天。,如果要實現群聊的話,只要把所有的socket儲存到集合中,有客戶輸入時遍歷socket得到輸出流並把訊息廣播給各個客戶端就行了。

四個讀寫的執行緒類都是一樣的,可以進行封裝,這裡就不封裝了。

Server伺服器主程式

package server;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {
	
	private ServerSocket serversocket;
	
	//構造方法
	public Server() {
		try {
			// 得到伺服器套接字
			serversocket = new ServerSocket(8888);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public void start() {
		try {
			while (true) {
				// 等待客戶端接入,並通過 套接字得到socket
				Socket socket = serversocket.accept();
				System.out.println("有客戶接入了");
				new Thread(new ServerReaderThread(socket)).start();
				new Thread(new ServerWriterThread(socket)).start();
			}

		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public static void main(String[] args) {
		Server server = new Server();
		server.start();
	}	
}


伺服器專門用來讀使用者資料的執行緒類

ServerReaderThread

package server;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;

public class ServerReaderThread implements Runnable{
	
	private Socket socket;
	private BufferedReader bf;
	private PrintWriter pw;
	
	public ServerReaderThread(Socket socket){
		this.socket = socket;
	}

	@Override
	public void run() {
		// TODO Auto-generated method stub
		// 得到輸入和輸出流
		InputStream is;
		try {
			is = socket.getInputStream();
			OutputStream os = socket.getOutputStream();
			// 包裝流
			bf = new BufferedReader(new InputStreamReader(is));
			pw = new PrintWriter(os);
			//迴圈讀取客戶端輸入的資料
			while(true){
				//讀取一行資料
				String info = bf.readLine();
				System.out.println(info);
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}


伺服器專門用來發送資料給客戶的執行緒類

ServerWriterThread

package server;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;

public class ServerWriterThread implements Runnable{
	
	private Socket socket;
	private BufferedReader bf;
	private PrintWriter pw;
	
	public ServerWriterThread(Socket socket){
		this.socket = socket;
	}

	@Override
	public void run() {
		// TODO Auto-generated method stub
		// 得到輸入和輸出流
		InputStream is;
		try {
			is = socket.getInputStream();
			OutputStream os = socket.getOutputStream();
			// 包裝流
			bf = new BufferedReader(new InputStreamReader(is));
			pw = new PrintWriter(os);
			Scanner sc = new Scanner(System.in);
			//迴圈讀取伺服器輸入的資料併發送給客戶端
			while(true){
				//讀取一行資料
				String info = sc.nextLine();
				pw.println(info);
				pw.flush();
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}


Client 客戶端主程式

package client;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class Client {

	private Socket socket;

	// 構造方法
	public Client() {
		try {
			// 得到連線到伺服器的socket
			socket = new Socket("localhost", 8888);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public void start() {
		// 等待客戶端接入,並通過 套接字得到socket
		new Thread(new ClientReaderThread(socket)).start();
		new Thread(new ClientWriterThread(socket)).start();
	}

	public static void main(String[] args) {
		Client client = new Client();
		client.start();
	}
}


客戶端用來讀取資料的執行緒類

ClientReaderThread

package client;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;

public class ClientReaderThread implements Runnable {

	private Socket socket;
	private BufferedReader bf;
	private PrintWriter pw;

	public ClientReaderThread(Socket socket) {
		this.socket = socket;
	}

	@Override
	public void run() {
		// TODO Auto-generated method stub
		// 得到輸入和輸出流
		InputStream is;
		try {
			is = socket.getInputStream();
			OutputStream os = socket.getOutputStream();
			// 包裝流
			bf = new BufferedReader(new InputStreamReader(is));
			pw = new PrintWriter(os);
			// 迴圈讀取客戶端輸入的資料
			while (true) {
				// 讀取一行資料
				String info = bf.readLine();
				System.out.println(info);
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}


客戶端用來發送訊息的執行緒類

ClientWriterThread

package client;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;

public class ClientWriterThread implements Runnable {

	private Socket socket;
	private BufferedReader bf;
	private PrintWriter pw;

	public ClientWriterThread(Socket socket) {
		this.socket = socket;
	}

	@Override
	public void run() {
		// TODO Auto-generated method stub
		// 得到輸入和輸出流
		InputStream is;
		try {
			is = socket.getInputStream();
			OutputStream os = socket.getOutputStream();
			// 包裝流
			bf = new BufferedReader(new InputStreamReader(is));
			pw = new PrintWriter(os);
			Scanner sc = new Scanner(System.in);
			// 迴圈讀取伺服器輸入的資料併發送給客戶端
			while (true) {
				// 讀取一行資料
				String info = sc.nextLine();
				pw.println(info);
				pw.flush();
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}