java網路程式設計二:伺服器處理多個使用者請求的解決方案(返回多個使用者輸入的資訊)

一個程式寫手發表於2011-10-28

1、用多個執行緒來同時為多個客戶提供服務,這是提高伺服器的併發效能的最常用的手段,那麼怎樣來為多個使用者提供服務呢?

     主要有三種方法:

     

2、為了更清楚理解伺服器到底是怎麼工作的,下面用第一種方式來處理多個使用者請求。如果想用第二、第三方式可以參考Touch的部落格:

java多執行緒總結五:執行緒池的原理及實現

 下面的示例中客戶端輸入資訊,伺服器端回覆相同的資訊,可以同時開啟多個客戶端,同時輸入資訊,原始碼如下:

伺服器端程式碼:

package demo.net;

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


/**
 * 伺服器返回使用者輸入的資訊, 為多個使用者提供服務:為每個客戶分配一個工作執行緒
 */
public class ChatServers {
	private int port = 8189;// 預設伺服器埠

	public ChatServers() {
	}

	// 建立指定埠的伺服器
	public ChatServers(int port) {
		this.port = port;
	}

	public void service() {
		int i=0;
		try {
			// 建立伺服器連線,設定客戶連線請求佇列的長度
			ServerSocket server = new ServerSocket(port,3);
			while (true) {
				// 等待客戶連線
				Socket socket = server.accept();
				i++;
				System.out.println("第"+i+"個客戶連線成功!");
				new Thread(new ServerThread(socket)).start();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public static void main(String[] args) {
		new ChatServers().service();
	}
}

class ServerThread implements Runnable {
	private Socket socket;

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

	// 任務是為一個使用者提供服務
	@Override
	public void run() {
		try {
			try {
				// 讀取客戶端傳過來資訊的DataInputStream
				DataInputStream in = new DataInputStream(socket
						.getInputStream());
				// 向客戶端傳送資訊的DataOutputStream
				DataOutputStream out = new DataOutputStream(socket
						.getOutputStream());
				while (true) {
					// 讀取來自客戶端的資訊
					String accpet = in.readUTF();
					out.writeUTF("伺服器:" + accpet);
				}
			} finally {// 建立連線失敗的話不會執行socket.close();
				socket.close();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}


客戶端程式碼:

package demo.net;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.util.Scanner;

/**
 * 注意用到的輸入輸出流DataInputStream和DataOutputStream,成對出現,最好用位元組流
 */
// 客戶端類
public class ChatClients {
	private String host = "localhost";// 預設連線到本機
	private int port = 8189;// 預設連線到埠8189

	public ChatClients() {

	}

	// 連線到指定的主機和埠
	public ChatClients(String host, int port) {
		this.host = host;
		this.port = port;
	}

	public void chat() {
		try {
			// 連線到伺服器
			Socket socket = new Socket(host, port);
			try {
				// 讀取伺服器端傳過來資訊的DataInputStream
				DataInputStream in = new DataInputStream(socket
						.getInputStream());
				// 向伺服器端傳送資訊的DataOutputStream
				DataOutputStream out = new DataOutputStream(socket
						.getOutputStream());

				// 裝飾標準輸入流,用於從控制檯輸入
				Scanner scanner = new Scanner(System.in);

				while (true) {
					String send = scanner.nextLine();
					// 把從控制檯得到的資訊傳送給伺服器
					out.writeUTF(send);
					// 讀取來自伺服器的資訊
					String accpet = in.readUTF();
					System.out.println(accpet);
				}

			} finally {
				socket.close();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public static void main(String[] args) {
		new ChatClients().chat();
	}
}


 

執行結果:

                                 

相關文章