java socket 編程 多線程異步通信


最近在學習分布式,分布式的前提是要知道網絡服務器的通信,自己對這一塊基本不了解,最近學習了一下,整理一個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編程的話,就沒有這個問題,因為輸入的面板和顯示面板是獨立開來的,呵呵

                       


免責聲明!

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



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