最近在學習分布式,分布式的前提是要知道網絡服務器的通信,自己對這一塊基本不了解,最近學習了一下,整理一個demo,方便以后查閱
這個是關於TCP/BIO,所謂BIO就是阻塞IO,沒收到消息時就處於阻塞狀態,有消息就工作,我用了多線程來處理收消息和發消息,實現了異步發送
服務器端代碼:
1 package internetCommunication; 2 3 import java.io.BufferedReader; 4 import java.io.IOException; 5 import java.io.InputStreamReader; 6 import java.io.PrintWriter; 7 import java.net.ServerSocket; 8 import java.net.Socket; 9 10 public class Server { 11 12 public static void main(String[] args) { 13 try { 14 ServerSocket server = new ServerSocket(8888); 15 Socket client = server.accept(); 16 BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream())); 17 PrintWriter out=new PrintWriter(client.getOutputStream()); 18 BufferedReader userin = new BufferedReader(new InputStreamReader(System.in)); 19 20 21 new ReceiveTread(server,in,out,userin,client).start(); 22 new SendThread(out, userin,true).start(); 23 } catch (IOException e) { 24 e.printStackTrace(); 25 } 26 27 28 } 29 30 }
客戶端代碼
1 package internetCommunication; 2 3 import java.io.BufferedReader; 4 import java.io.IOException; 5 import java.io.InputStreamReader; 6 import java.io.PrintWriter; 7 import java.net.InetAddress; 8 import java.net.Socket; 9 10 public class Client { 11 12 13 public static void main(String[] args) { 14 try { 15 Socket server = new Socket(InetAddress.getLocalHost(), 8888); 16 BufferedReader in = new BufferedReader(new InputStreamReader(server.getInputStream())); 17 PrintWriter out=new PrintWriter(server.getOutputStream()); 18 BufferedReader userin = new BufferedReader(new InputStreamReader(System.in)); 19 20 new SendThread(out,userin,false).start(); 21 new ReceiveTread(server,in,out,userin).start(); 22 23 24 } catch (IOException e) { 25 e.printStackTrace(); 26 } 27 28 29 } 30 }
發消息多線程類
1 package internetCommunication; 2 3 import java.io.BufferedReader; 4 import java.io.IOException; 5 import java.io.PrintWriter; 6 import java.text.SimpleDateFormat; 7 import java.util.Date; 8 9 public class SendThread extends Thread{ 10 11 PrintWriter out; 12 BufferedReader userin; 13 boolean isServer; 14 15 public SendThread(PrintWriter out,BufferedReader userin,boolean isServer) { 16 this.out = out; 17 this.userin = userin; 18 this.isServer = isServer; 19 } 20 21 @Override 22 public void run() { 23 SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 24 25 try { 26 while(true){ 27 if(isServer){ 28 out.println("Server "+sf.format(new Date())+"\n\t"+ userin.readLine()); 29 }else{ 30 out.println("client "+sf.format(new Date())+"\n\t"+ userin.readLine()); 31 } 32 out.flush(); 33 } 34 } catch (IOException e) { 35 e.printStackTrace(); 36 } 37 38 } 39 40 41 42 43 44 45 }
接消息多線程類
1 package internetCommunication; 2 3 import java.io.BufferedReader; 4 import java.io.IOException; 5 import java.io.PrintWriter; 6 import java.net.ServerSocket; 7 import java.net.Socket; 8 9 public class ReceiveTread extends Thread{ 10 BufferedReader in ; 11 ServerSocket server; 12 PrintWriter out; 13 BufferedReader userin; 14 Socket client; 15 16 17 public ReceiveTread(ServerSocket server,BufferedReader in,PrintWriter out,BufferedReader userin,Socket client) { 18 this.in = in; 19 this.server = server; 20 this.client = client; 21 this.out = out; 22 this.userin = userin; 23 } 24 25 public ReceiveTread(Socket client ,BufferedReader in,PrintWriter out,BufferedReader userin) { 26 this.in = in; 27 this.client = client; 28 this.out = out; 29 this.userin = userin; 30 } 31 32 33 @Override 34 public void run() { 35 try { 36 while(true){ 37 String info = in.readLine(); 38 while(info !=null){ 39 System.out.println(info); 40 info = in.readLine(); 41 } 42 if(in.readLine().equals("end")){ 43 break; 44 } 45 } 46 in.close(); 47 out.close(); 48 userin.close(); 49 if(client != null){ 50 client.close(); 51 } 52 server.close(); 53 } catch (IOException e) { 54 e.printStackTrace(); 55 } 56 } 57 }
以下是控制輸出:
這是客戶端的
這是服務器的:
這里要注意的是: 1、啟動時要先啟動服務器,在啟動客戶端,因為只有服務器啟動了,開始監聽某個端口,客戶端才能連上
2、因為輸入控制台和輸出控制台都揉在一起顯示,控制台顯示接收消息的時候,光標還是會停留在上一次輸入的地方,如果輸入非漢字類的,光標會自動跳下來
但是輸入漢字,會出現把接收到消息也發送的情況,所以需要輸入的時候將光標自己點下來,如果是GUI編程的話,就沒有這個問題,因為輸入的面板和顯示面板是獨立開來的,呵呵