java網路程式設計

Diy_os發表於2015-11-12
對於網路方面的知識在這裡不作詳細的介紹,讀者可以參考《TCP/IP詳解 I II III》等網路書籍。

下面簡單的談下網路通訊協議和網路通訊協議介面。

網路通訊協議:計算機網路中實現通訊必須有一些約定即通訊協議,對速率,傳輸程式碼,程式碼結構,傳輸控制步驟,出錯控制等制定標準。
網路通訊介面:為了使兩個結點之間能進行對話,必須在它們之間建立通訊工具(即介面),使得彼此之間能進行資訊交換。介面包括兩部分:
java中提供了兩種常見的網路協議支援,TCP/UDP,關於這這兩種協議,懂網路基礎知識的朋友都知道這兩種協議屬於OSI(TCP/IP)中運輸層的協議,在TCP/IP中,把OSI簡化為四層,其中運輸層與應用層直接互動。

下面簡單的介紹TCP/UDP協議:
TCP:是專門設計用於在不可靠的因特網上提供可靠的,端到端的位元組流通訊協議,它是一種面向連線的協議。TCP連線是位元組流而非報文流。
UDP:嚮應用程式提供了了一種傳送封裝的原始IP資料包(包,分組)的方法,並且傳送時無需建立連線,是一種不可靠的連線,但是效率高,廣泛的運用在影片傳輸,語音通話等通訊中。

Socket 程式設計是使用最廣泛的網路概念套接字使用TCP提供了兩臺計算機之間的通訊機制。 客戶端程式建立一個套接字,並嘗試連接伺服器的套接字。當連線建立時,伺服器會建立一個Socket物件。客戶端和伺服器現在可以透過對Socket物件的寫入和讀取來進行進行通訊。java.net.Socket類代表一個套接字,並java.net.ServerSocket類為伺服器程式提供了一種來監聽客戶端,並與他們建立連線的機制。
以下步驟在兩臺計算機之間使用套接字建立TCP連線時會出現:
伺服器例項化一個ServerSocket物件,表示透過伺服器上的埠通訊,該物件很像監聽器,監聽客戶端是否有使用者來連線。伺服器呼叫 ServerSocket類 的accept()方法,該方法將一直等待,直到客戶端連線到服務器上給定的埠。伺服器正在等待時,一個客戶端例項化一個Socket物件,指定伺服器名稱和埠號來請求連接。Socket類的建構函式試圖將客戶端連線到指定的伺服器和埠號。如果通訊被建立,則在客戶端建立一個Socket物件能夠與伺服器進行通訊。在伺服器端,accept()方法返回伺服器上一個新的socket引用,該socket連線到客戶端的socket。連線建立後,透過使用I/O流在進行通訊。每一個socket都有一個輸出流和一個輸入流。客戶端的輸出流連線到伺服器端的輸入流,而客戶端的輸入流連線到伺服器端的輸出流。TCP是一個雙向的通訊協議,因此資料可以透過兩個資料流在同一時間傳送.以下是一些類提供的一套完整的有用的方法來實現sockets。具體方法詳見
java.net包中定義的兩個類Scoket和ServerScoket。
以上client與server通訊過程可以簡單的用下面的示意圖來表示:
                                                                                                           

下面客戶端與伺服器端進行簡單的TCP協議通訊:

點選(此處)摺疊或開啟

  1. public class TCPServer {
  2.   public static void main(String[] args){
  3.     
  4.      try {
  5.         @SuppressWarnings("resource")
  6.         ServerSocket server = new ServerSocket(11111);
  7.         Socket ser = server.accept();
  8.         DataInputStream in = new DataInputStream(ser.getInputStream());
  9.         OutputStream ou = ser.getOutputStream();
  10.         DataOutputStream out = new DataOutputStream(ou);
  11.         out.writeUTF("hi!Client!");
  12.         System.out.println(in.readUTF());
  13.         out.flush();
  14.         out.close();
  15.     } catch (IOException e) {
  16.         // TODO 自動生成的 catch 塊
  17.         e.printStackTrace();
  18.     } 
  19.   }
  20. }

  21. public class TCPClient {
  22.    public static void main(String[] args){
  23.     
  24.      try {
  25.         @SuppressWarnings("resource")
  26.         Socket client = new Socket("127.0.0.1",11111);
  27.         OutputStream out = client.getOutputStream();
  28.         DataOutputStream data = new DataOutputStream(out);
  29.         DataInputStream inn = new DataInputStream(client.getInputStream());
  30.         System.out.println(inn.readUTF());
  31.         data.writeUTF("hi!server!");
  32.         data.flush();
  33.         data.close();
  34.         inn.close();
            client.close();

  35.     } catch (UnknownHostException e) {
  36.         e.printStackTrace();
  37.     } catch (IOException e) {
  38.         e.printStackTrace();
  39.      }
  40.    }
  41. }


從上面看出,client端發出與ip為127.0.0.1,埠號為11111的伺服器進行socket通訊,並且對伺服器端發出問候,此時伺服器端的accept()正在監視11111埠,如果有socket請求,則馬上建立連線,並把從客戶端發來的資訊列印出來,此時伺服器端也向客戶端發出問候,並列印結果:



上面只是簡單的一對一進行通訊,可以多個客戶端對一個伺服器端發出通訊請求,  對上面的程式碼進行修改就可以簡單實現,再新增一個客戶端類TCPClient1,程式碼如下:

點選(此處)摺疊或開啟

  1. public class TCPServer {
  2.   public static void main(String[] args){
  3.     
  4.      try {
  5.          @SuppressWarnings("resource")
  6.         ServerSocket server = new ServerSocket(11111);
  7.         while(true){
  8.          Socket ser = server.accept();
  9.         DataInputStream in = new DataInputStream(ser.getInputStream());
  10.         OutputStream ou = ser.getOutputStream();
  11.         DataOutputStream out = new DataOutputStream(ou);
  12.         out.writeUTF("hi!Client!");
  13.         System.out.println(in.readUTF());
  14.         out.flush();
  15.         out.close();
  16.         }
  17.        
  18.     } catch (IOException e) {
  19.         // TODO 自動生成的 catch 塊
  20.         e.printStackTrace();
  21.     } 
  22.   }
  23. }

  24. public class TCPClient {
  25.      public static void main(String[] args){
  26.         
  27.          try {
  28.             @SuppressWarnings("resource")
  29.             Socket client = new Socket("127.0.0.1",11111);
  30.             OutputStream out = client.getOutputStream();
  31.             DataOutputStream data = new DataOutputStream(out);
  32.             DataInputStream inn = new DataInputStream(client.getInputStream());
  33.          System.out.println(inn.readUTF());
  34.             data.writeUTF("hi!server!");
  35.             data.flush();
  36.             data.close();
  37.             inn.close();
  38.             client.close();
  39.         } catch (UnknownHostException e) {
  40.             // TODO 自動生成的 catch 塊
  41.             e.printStackTrace();
  42.         } catch (IOException e) {
  43.             // TODO 自動生成的 catch 塊
  44.             e.printStackTrace();
  45.         }
  46.       }
  47.     }


  48. public class TCPClient1 {
  49.  
  50.      public static void main(String[] args){
  51.         
  52.          try {
  53.             @SuppressWarnings("resource")
  54.             Socket client = new Socket("127.0.0.1",11111);
  55.             OutputStream out = client.getOutputStream();
  56.             DataOutputStream data = new DataOutputStream(out);
  57.             DataInputStream inn = new DataInputStream(client.getInputStream());
  58.          System.out.println(inn.readUTF());
  59.             data.writeUTF("hi!server!");
  60.             data.flush();
  61.             data.close();
  62.             inn.close();
  63.             client.close();
  64.         } catch (UnknownHostException e) {
  65.             // TODO 自動生成的 catch 塊
  66.             e.printStackTrace();
  67.         } catch (IOException e) {
  68.             // TODO 自動生成的 catch 塊
  69.             e.printStackTrace();
  70.          }
  71.       }
  72.    }


下面談談基於UDP協議的網路通訊,由於UDP通訊是傳送的IP資料包,無需建立連線,是一種不可靠的連線,這和TCP通訊有很大的區別。

點選(此處)摺疊或開啟

  1. public class UDPServer {
  2.   public static void main(String[] args){
  3.     
  4.      byte b[] = new byte[1000];
  5.      DatagramPacket dp = new DatagramPacket(b, b.length);
  6.          ByteArrayOutputStream by = new ByteArrayOutputStream();
  7.          DataOutputStream byt = new DataOutputStream(by);
  8.         
  9.         try {
  10.                 DatagramSocket ds = new DatagramSocket(111);
  11.                 ds.receive(dp);
  12.                 ByteArrayInputStream bais = new ByteArrayInputStream(b);
  13.                 DataInputStream dis = new DataInputStream(bais);
  14.                 System.out.println(dis.readUTF());
  15.                 byt.writeUTF("hi!Client!");
  16.                 byte c[] = by.toByteArray();
  17.                 DatagramPacket dpp = new DatagramPacket(c, c.length,new InetSocketAddress("127.0.0.1", 1111));
  18.                 DatagramSocket dss = new DatagramSocket();
  19.                 dss.send(dpp);
  20.                } catch (SocketException e1) {
  21.             // TODO 自動生成的 catch 塊
  22.             e1.printStackTrace();
  23.         } catch (IOException e) {
  24.             // TODO 自動生成的 catch 塊
  25.             e.printStackTrace();
  26.         }
  27.     }
  28. }
  29. public class UDPClient {
  30.    public static void main(String[] args){
  31.     
  32.     
  33.      ByteArrayOutputStream w = new ByteArrayOutputStream();
  34.      DataOutputStream ou = new DataOutputStream(w);
  35.      byte d[] = new byte[1000];
  36.      DatagramPacket dpp = new DatagramPacket(d, d.length);
  37.     
  38.     
  39.      try {
  40.         
  41.         DatagramSocket dss = new DatagramSocket(1111);
  42.         ou.writeUTF("hi,Server!");
  43.         byte a[] = w.toByteArray();
  44.         DatagramPacket dp = new DatagramPacket(a, a.length,new InetSocketAddress("127.0.0.1", 111));
  45.         DatagramSocket ds = new DatagramSocket();
  46.         ds.send(dp);
  47.         dss.receive(dpp);
  48.         ByteArrayInputStream bais = new ByteArrayInputStream(d);
  49.         DataInputStream dis = new DataInputStream(bais);
  50.         System.out.println(dis.readUTF());
  51.     } catch (IOException e) {
  52.         // TODO 自動生成的 catch 塊
  53.         e.printStackTrace();
  54.      }
  55.    }
  56. }
以上同樣是server與Client端相互通訊,和TCP協議通訊有很大的區別,其中有很多的細節還需要注意。雖然UDP不需要建立連線,但是在網路傳送中,需要告訴它目的主機IP,以及應用程式埠號,然後經過層層的封裝,然後由底層物理鏈路傳送位元流。
以上作為個人學習總結,有很多知識沒有總結到,比如URL,URI類。上文如有不當或錯誤之處,請讀者指正!謝謝!

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29876893/viewspace-1830004/,如需轉載,請註明出處,否則將追究法律責任。

相關文章