Java 網絡編程--------------------基於TCP/IP(加入多線程)


Java 網絡編程--------------------基於TCP/IP(加入多線程)


1、服務器類:


package com.serversocket;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Server_02 {
	//定義保存所有Socket的ArrayList,並將其包裝爲線程安全的
	public static List<Socket> socketList = Collections.synchronizedList(new ArrayList<>());
	
	public static void main(String[] args) throws IOException {
		
		ServerSocket ss = new ServerSocket(30000);
		
		while(true){
			//此行代碼會阻塞,會一直等待別人的鏈接
			Socket s = ss.accept();
			socketList.add(s);
			//每當客戶端連接成功後啓動一個ServerThread線程爲該客戶端服務
			new Thread(new ServerThread02(s)).start();
		}
	}
}


2、服務器線程類


package com.serversocket;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;

public class ServerThread02 implements Runnable {
	
	//定義當前線程處理的Socket
	Socket s = null;
	//該線程所處理的Socket的輸入流
	BufferedReader br = null;

	public ServerThread02(Socket s) throws IOException {
		this.s = s;
		//初始化該Socket所對應的輸入流
		br = new BufferedReader(new InputStreamReader(s.getInputStream()));
	}

	public void run() {
		try {
			String content = null;
			//採用循環不斷的從Socket中讀取客戶端發送過來的數據
			while ((content = readFromClient()) != null) {
				//遍歷socketList中的每個Socket
				//將讀到的內容向每個Socket發送一次
				for (Socket s : Server_02.socketList) {
					PrintStream ps = new PrintStream(s.getOutputStream());
					ps.println(content);
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	//定義讀取客戶端數據的方法
	private String readFromClient() {
		try { 
			return br.readLine();
			//如果捕獲到異常,則表明Socket對應的客戶端已經關閉
		} catch (IOException e) {
			//刪除該Socket
			Server_02.socketList.remove(s);
		}
		return null;
	}
}


3、客戶端類


package com.socket;

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

public class Client_02 {

	public static void main(String[] args) throws Exception {
		
		Socket s = new Socket("127.0.0.1",30000);
		
		//客戶端啓動ClientThread02不斷的讀取來自服務器的數據
		
		new Thread(new ClientThread02(s)).start();
		
		PrintStream ps = new PrintStream(s.getOutputStream());
		
		String line = null;
		System.out.println("請輸入消息:");
		//不斷讀取鍵盤的輸入
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		
		while((line = br.readLine())!=null){
			//將用戶的鍵盤輸入內容寫入Socket對應的輸出流
			ps.println(line);
		}
	}
}


4、客戶端線程類


package com.socket;

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

public class ClientThread02 implements Runnable {
	//該線程負責處理的Socket
	private Socket s = null;
	//該線程處理的Socket對應的輸入流
	BufferedReader br = null;
	
	public ClientThread02(Socket s) throws IOException{
		this.s = s;
		br = new BufferedReader(new InputStreamReader(s.getInputStream()));
	}
	
	@Override
	public void run() {

		try{
			String content = null;
			//不斷讀取Socket輸入流中的內容,並將這些內容打印輸出
			while((content=br.readLine()) != null){
				System.out.println(content);
			}
		}catch(IOException e){
			e.printStackTrace();
		}
	}
}


    編寫好上面代碼之後,首先啓動服務器類,然後再啓動客戶端類(可以啓動多個客戶端類)

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