簡單類比多線程Socket通訊(java)

來源:互聯網
上載者:User

         先來看一段單線程的原始代碼(代碼中有詳細的注釋):

 

         伺服器(TCPServer.java):


import java.net.*;import java.io.*;public class TCPServer{  public static void main(String[] args) throws Exception{    ServerSocket ss = new ServerSocket(5566); //建立一個Socket伺服器,監聽5566連接埠    int i=0;    //利用死迴圈不停的監聽連接埠    while(true){      Socket s = ss.accept(); //利用Socket伺服器的accept()方法擷取用戶端Socket對象。      i++;      System.out.println("第" + i +"個用戶端成功串連。");      DataInputStream dis = new DataInputStream(s.getInputStream()); //擷取用戶端Socket對象的輸入資料流,並在外邊加一層DataInputStream管道,目的是方便讀取資料      System.out.println(dis.readUTF()); //讀出流中的資料,DataInputStream對象的readUTF()方法可以讀出流中的資料,而且支援中文      dis.close(); //關閉管道串連      s.close(); //關閉Socket串連    }  }}

        用戶端(TCPClient.java):


import java.net.*;import java.io.*;public class TCPClient{  public static void main(String[] args) throws Exception{    Socket s = new Socket("192.168.24.177",5566); //建立一個Socket對象,串連IP地址為192.168.24.177的伺服器的5566連接埠    DataOutputStream dos = new DataOutputStream(s.getOutputStream()); //擷取Socket對象的輸出資料流,並且在外邊包一層DataOutputStream管道,方便輸出資料    dos.writeUTF("用戶端訊息"); //DataOutputStream對象的writeUTF()方法可以輸出資料,並且支援中文    dos.flush(); //確保所有資料都已經輸出    dos.close(); //關閉輸出資料流    s.close(); //關閉Socket串連  }}


        以上代碼利用Socket對象和ServerSocket對象進行簡單的網路互動,即用戶端通過DataOutputStream對象的writeUTF()方法向伺服器發送訊息,伺服器利用DataInputStream對象的readUTF()方法讀出資料。

        看上去挺好,但ServerSocket對象的accept()方法是阻塞的方法,它會一直等待,直到有用戶端串連。

        同理,DataInputStream對象的readUTF()方法也是阻塞的方法,它也會一直等待,直到用戶端調用writeUTF()方法。

        因此,假如某個用戶端成功串連伺服器,但是遲遲不調用writeUTF()方法發送資料,伺服器就要一直等待,直到用戶端調用writeUTF()方法為止,此期間整個伺服器是阻塞的,無法再接受其他用戶端串連,顯然這不符合實際情況。

        要解決這個問題,當然要用多線程。

        如果每個用戶端都專屬一個線程,讓readUTF()方法阻塞用戶端專屬的線程,而不去阻塞伺服器主線程,這樣伺服器就可以同時接受多個用戶端串連,而不用考慮用戶端何時調用writeUTF()方法發送資料。代碼如下:

 

        伺服器(TCPServer.java):

import java.net.*;import java.io.*;public class TCPServer{  public static void main(String[] args) throws Exception{    ServerSocket ss = new ServerSocket(5566); //建立一個Socket伺服器,監聽5566連接埠    int i=0;    //利用死迴圈不停的監聽連接埠    while(true){      Socket s = ss.accept();//利用Socket伺服器的accept()方法擷取用戶端Socket對象。      i++;      System.out.println("第" + i +"個用戶端成功串連。");      Client c = new Client(i,s); //建立用戶端處理線程對象      Thread t =new Thread(c); //建立用戶端處理線程      t.start(); //啟動線程    }  }}//用戶端處理線程類(實現Runnable介面)class Client implements Runnable{  int clientIndex = 0; //儲存用戶端id  Socket s = null; //儲存用戶端Socket對象    Client(int i,Socket s){    clientIndex = i;    this.s = s;  }    public void run(){    //列印出用戶端資料    try{      DataInputStream dis = new DataInputStream(s.getInputStream());      System.out.println("第" + clientIndex + "個用戶端發出訊息:" + dis.readUTF());      dis.close();      s.close();    }    catch(Exception e)    {}  }}

        用戶端(TCPClient.java):

import java.net.*;import java.io.*;public class TCPClient{  public static void main(String[] args) throws Exception{    Socket s = new Socket("192.168.24.177",5566); //建立一個Socket對象,串連IP地址為192.168.24.177的伺服器的5566連接埠    DataOutputStream dos = new DataOutputStream(s.getOutputStream()); //擷取Socket對象的輸出資料流,並且在外邊包一層DataOutputStream管道,方便輸出資料    Thread.sleep((int)(Math.random()*3000)); //讓用戶端不定時向伺服器發送訊息    dos.writeUTF("用戶端訊息"); //DataOutputStream對象的writeUTF()方法可以輸出資料,並且支援中文    dos.flush(); //確保所有資料都已經輸出    dos.close(); //關閉輸出資料流    s.close(); //關閉Socket串連  }}


        運行結果如下(參考結果,不一定相同。):


        明顯看出第2、3、4用戶端都沒有向伺服器端發出訊息,但都成功串連,而且第2、3、4用戶端向伺服器發出訊息也沒有順序。

        通過多線程,實現了多個用戶端同時串連伺服器,並且伺服器能即時處理多個用戶端發出的訊息。

        以上僅僅是作為初學者的一些想法,僅供參考。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.