首頁  >  文章  >  Java  >  Java網路程式設計的一些心得

Java網路程式設計的一些心得

零下一度
零下一度原創
2017-07-17 13:11:592489瀏覽

  最近在學習Java網路編程,之前聽說過,但一直都沒有認真了解過。這幾天突然來了興致,覺得很神奇,忽然就想要了解下具體是什麼個情況。

        Socket通常也稱為"套接字",用於描述IP位址和端口,是一個通訊鏈的句柄。在Internet上的主機一般運行了多個服務軟體,同時提供幾種服務。每種服務都開啟一個Socket,並綁定到一個連接埠上,不同的連接埠對應於不同的服務。


       Socket非常類似電話插座。以一個國家級電話網為例,電話的通話雙方相當於相互通訊的2個進程,區號是它的網路位址;區內一個單位的交換機相當於一台主機,主機分配給每個用戶的局內號碼相當於Socket號。任何用戶在通話之前,首先要佔有一部電話機,相當於申請一個Socket;同時要知道對方的號碼,相當於對方有一個固定的Socket。然後向對方撥號呼叫,相當於發出連線請求(如果對方不在同一區內,還要撥對方區號,相當於給網路位址)。假如對方在場並空閒(相當於通訊的另一主機開機且可以接受連線要求),拿起電話話筒,雙方就可以正式通話,相當於連線成功。雙方通話的過程,是一方向電話機發出訊號和對方從電話機接收訊號的過程,相當於向Socket發送資料和從socket接收資料。通話結束後,一方掛起電話機相當於關閉Socket,撤銷連線。


        在電話系統中,一般使用者只能感受到本地電話機和對方電話號碼的存在,建立通話的過程,文字傳輸的過程以及整個電話系統的技術細節對他都是透明的,這也與Socket機制非常​​相似。 Socket利用網間網路通訊設施實現進程通信,但它對通訊設施的細節毫不關心,只要通訊設施能提供足夠的通訊能力,它就滿足了。
以上這些都是百度百科裡面的定義與解釋,不過看著也還蠻容易理解的,不像之前有的解釋很不容易理解,專業術語太多,理解起來特別費力。


Socket通訊實現步驟:
        1、建立ServerSocket與Socket
        2、開啟連接Socket的對Socket進行讀寫作業
        4、關閉輸入/輸出流,並關閉Socket

Socket程式設計

##一個是ServerSocket,一個是Socket。服務端和客戶端之間透過Socket建立連接,之後它們就可以進行通訊了。首先ServerSocket將在服務端監聽某個端口,當發現客戶端有Socket來試圖連接它時,它會accept該Socket的連接請求,同時在服務端建立一個對應的Socket與之進行通信。這樣就有兩個Socket了,客戶端和服務端各一個。

對於Socket之間的通訊其實很簡單,服務端往Socket的輸出流裡面寫東西,客戶端就可以透過Socket的輸入流讀取對應的內容。 Socket與Socket之間是雙向連通的,所以客戶端也可以往對應的Socket輸出流裡面寫東西,然後服務端對應的Socket的輸入流就可以讀出對應的內容。



Java網路程式設計的一些心得下面是一個例子,客戶端讀寫與服務端讀寫

服務端程式碼

public class Server {
public static void main(String args[]) throws IOException {
      //定义一个ServerSocket监听在端口8888上  
      int port = 8888; 
      int i=1; //连接计数
      //server尝试接收其他Socket的连接请求,
      ServerSocket server = new ServerSocket(port);  
      //server的accept方法是阻塞式的 ,即等待着客户端的请求
      Socket socket = server.accept();  
      System.out.println("连接"+i++);
      //跟客户端建立好连接,我们就可以获取socket的InputStream,从中读取客户端发过来的信息。  
      Reader reader = new InputStreamReader(socket.getInputStream());    
      char chars[] = new char[64];  
      int len;  
      StringBuilder sb = new StringBuilder();  
      String temp;  
      int index;  
      while ((len=reader.read(chars)) != -1) {  
         temp = new String(chars, 0, len);  
         if ((index = temp.indexOf("eof")) != -1) { //遇到eof时就结束接收  
            sb.append(temp.substring(0, index));  
            break;  
         }  
         sb.append(temp);  
      }  
      System.out.println("from client: " + sb);  
      //读完后写数据 
      Writer writer = new OutputStreamWriter(socket.getOutputStream());  
      writer.write("Hello Client:我是服务端输入数据"); 
      //释放资源
      writer.flush();  
      writer.close(); 
      reader.close();  
      socket.close();  
      server.close(); 
   }  
}

輸出

Java網路程式設計的一些心得注意點

    服務端從Socket的InputStream中讀取資料的操作也是阻塞式的,如果從輸入流中沒有讀取到資料程序會一直在那裡不動,直到客戶端往Socket的輸出流中寫入了數據,或關閉了Socket的輸出流。當然,對於客戶端的Socket也是同樣如此。
  • 輸入流中讀取客戶端發送過來的數據,接下來我們再往輸出流裡面寫入資料給客戶端,接下來關閉對應的資源檔。而實際上上述程式碼可能不會按照我們預先設想的方式運行,因為從輸入流中讀取資料是一個阻塞式操作,在上述的while循環中當讀到資料的時候就會執行循環體,否則就會阻塞,這樣後面的寫入操作就永遠都執行不了了,針對這種情況,通常我們都會約定一個結束標記,當客戶端發送過來的資料包含某個結束標記時就表示當前的資料已經發送完畢了,這個時候我們就可以進行循環的跳出了。
  • 在上述代码中,当服务端读取到客户端发送的结束标记,即“eof”时就会结束数据的接收,终止循环,这样后续的代码又可以继续进行了。

客户端代码

public class Client {
 public static void main(String args[]) throws Exception {  
      //为了简单起见,所有的异常都直接往外抛  
      String host = "192.168.74.1";  //要连接的服务端IP地址  
      int port = 8888;   //要连接的服务端对应的监听端口  
      //与服务端建立连接  
      Socket client = new Socket(host, port);  
      //建立连接后就可以往服务端写数据了  
      Writer writer = new OutputStreamWriter(client.getOutputStream());  
      writer.write("Hello ,我是客户端输入数据");
      writer.write("eof"); 
      writer.flush();//写完后要记得flush  
      //读取来自服务端数据
      Reader reader = new InputStreamReader(client.getInputStream());  
      char chars[] = new char[64];  
      int len;  
      StringBuffer sb = new StringBuffer();  
      String temp;  
      int index;  
      while ((len=reader.read(chars)) != -1) {  
         temp = new String(chars, 0, len);  
         if ((index = temp.indexOf("eof")) != -1) {  
            sb.append(temp.substring(0, index));  
            break;  
         }  
         sb.append(new String(chars, 0, len));  
      }  
      System.out.println("from server: " + sb);
      writer.close(); 
      reader.close();  
      client.close();  
   }  
}

输出

Java網路程式設計的一些心得

注意点

  • 过程:先是给服务端发送了一段数据,之后读取服务端返回来的数据,跟之前的服务端一样在读的过程中有可能导致程序一直挂在那里,永远跳不出while循环,解决方法和服务端一样,用一个结束标志。

  • 对于客户端往Socket的输出流里面写数据传递给服务端要注意一点,如果写操作之后程序不是对应着输出流的关闭,而是进行其他阻塞式的操作(比如从输入流里面读数据),记住要flush一下,只有这样服务端才能收到客户端发送的数据,否则可能会引起两边无限的互相等待。在稍后讲到客户端和服务端同时读和写的时候会说到这个问题。

以上是Java網路程式設計的一些心得的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn