面向Socket編程


前段時間做了一個面向Socket編程的項目,現在有時間和大家分享一下

首先是線程池:

Java通過Executors提供四種線程池,分別為:
newCachedThreadPool創建一個可緩存線程池,如果線程池長度超過處理需要,可靈活回收空閑線程,若無可回收,則新建線程。
newFixedThreadPool 創建一個定長線程池,可控制線程最大並發數,超出的線程會在隊列中等待。
newScheduledThreadPool 創建一個定長線程池,支持定時及周期性任務執行。
newSingleThreadExecutor 創建一個單線程化的線程池,它只會用唯一的工作線程來執行任務,保證所有任務按照指定順序(FIFO, LIFO, 優先級)執行

這里我用的是newCachedThreadPool,因為要滿足多用戶短連接的需求,newFixedThreadPool可能也是一種好的選擇,因為它避免多次開啟關閉線程造成的資源浪費,但考慮到當沒用線程執行時,線程依然開啟,浪費資源,就沒有使用。newScheduledThreadPool和newSingleThreadExecutor不滿足該項目需求。由於項目既需要接收數據又需要發送數據,就開啟了兩個Socket端口,而socket.accept()方法阻塞式的,在開啟端口前就需要先通過 ExecutorService exc = Executors.newCachedThreadPool()方式創建線程池,在其中可以指定最大可創建線程數,默認值為1000.下面就是執行代碼:

//獲得當前正在執行的線程數

int count=((ThreadPoolExecutor)exec).getActiveCount();
//執行線程
exec.execute(new Task(client));

這里很重要的一點是Task這個類必須要實現Runnable接口,我這里面吧連接的通道傳到Task中,然后通過socket.getInputStream()得到字節流,為了方便處理把它轉化為字符流,new BufferedReader(new InputStreamReader(socket.getInputStream()));以及new PrintWriter(socket.getOutputStream(),true);

而且在實踐過程發現重要一點,通道的一端發送數據后立刻關閉通道,在另一端依然可以接受到數據。特意寫個測試代碼給大家實踐,包需要你們自己導入。

服務器端代碼:

 1 public class Server {
 2     static ServerSocket server;
 3 
 4     public static void main(String[] args) {
 5 
 6         try {
 7             server = new ServerSocket(8100);
 8             while (true) {
 9                 Socket socket = server.accept();
10                 PrintWriter pw = new PrintWriter(socket.getOutputStream(), true);
11                 pw.println("hi:客戶端");
12                 pw.close();
13                 socket.close();
14                 System.out.println("服務器已經關閉");
15             }
16         } catch (IOException e) {
17 
18             e.printStackTrace();
19         }
20 
21     }
22 
23 }

客戶端代碼:

public class Cilent {
	public static void main(String[] args) {
		try {
			String s = "";
			Socket socket = new Socket("localhost", 8100);
			Thread.sleep(2000);
			BufferedReader bf = new BufferedReader(new InputStreamReader(
					socket.getInputStream()));

			if ((s = bf.readLine()) != null) {
				System.out.println(s);
			}
			socket.close();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

}

研究后我想可能是因為

客戶端 服務端
out-----x------->in
in<--------------out

=========================================================================================================

今天更到這里,后面會介紹一下如何利用osm數據畫自己的地圖,以及用java實現基於硬盤的TPR樹。歡迎感興趣的小伙伴一起討論啊

 


免責聲明!

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



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