【網路程式設計】socket詳解

love_Aym發表於2018-04-21

轉載:http://www.qqread.com/java/w592395600.html

    Socket是網路上執行的兩個程式間雙向通訊的一端,它既可以接受請求,也可以傳送請求,利用它可以較為方便的編寫網路上資料的傳遞。在Java中,有專門的Socket類來處理使用者的請求和響應。利用Socket類的方法,就可以實現兩臺計算機之間的通訊。這裡就介紹一下在Java中如何利用Socket進行網路程式設計。 

  在Java中Socket可以理解為客戶端或者伺服器端的一個特殊的物件,這個物件有兩個關鍵的方法,一個是getInputStream方法,另一個是getOutputStream方法。getInputStream方法可以得到一個輸入流,客戶端的Socket物件上的getInputStream方法得到的輸入流其實就是從伺服器端發回的資料流。GetOutputStream方法得到一個輸出流,客戶端Socket物件上的getOutputStream方法返回的輸出流就是將要傳送到伺服器端的資料流,(其實是一個緩衝區,暫時儲存將要傳送過去的資料)。

  程式可以對這些資料流根據需要進行進一步的封裝。本文的例子就對這些資料流進行了一定的封裝(關於封裝可以參考Java中流的實現部分)。

  為了更好的說明問題,這裡舉了一個網上對話的例子,客戶端啟動以後,伺服器會啟動一個執行緒來與客戶進行文字交流。

  要完成這個工作,需要完成三個部分的工作,以下依次說明:

  一、建立伺服器類

  Java中有一個專門用來建立Socket伺服器的類,名叫ServerSocket,可以用伺服器需要使用的埠號作為引數來建立伺服器物件。

    ServerSocket server = new ServerSocket(9998) 

  這條語句建立了一個伺服器物件,這個伺服器使用9998號埠。當一個客戶端程式建立一個Socket連線,所連線的埠號為9998時,伺服器物件server便響應這個連線,並且server.accept()方法會建立一個Socket物件。伺服器端便可以利用這個Socket物件與客戶進行通訊。

    Socket incoming = server.accept() 

  進而得到輸入流和輸出流,並進行封裝

    BufferedReader in = new BufferedReader(new 
                                                InputStreamReader(incoming.getInputStream()));
    PrintWriter out = new PrintWriter(incoming.getOutputStream(),true); 

  隨後,就可以使用in.readLine()方法得到客戶端的輸入,也可以使用out.println()方法向客戶端傳送資料。從而可以根據程式的需要對客戶端的不同請求進行回應。

  在所有通訊結束以後應該關閉這兩個資料流,關閉的順序是先關閉輸出流,再關閉輸入流,即使用 

out.close();
in.close(); 

二、建立客戶端程式碼

  相比伺服器端,客戶端要簡單一些,客戶端只需用伺服器所在機器的ip以及伺服器的埠作為引數建立一個Socket物件。得到這個物件後,就可以用"建立伺服器"部分介紹的方法實現資料的輸入和輸出。

Socket socket = new Socket("168.160.12.42",9998);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream(),true); 

  以上的程式程式碼建立了一個Socket物件,這個物件連線到ip地址為168.160.12.42的主機上、埠為9998的伺服器物件。並且建立了輸入流和輸出流,分別對應伺服器的輸出和客戶端的寫入。



轉載:http://www.cnblogs.com/skynet/

“一切皆Socket!”

話雖些許誇張,但是事實也是,現在的網路程式設計幾乎都是用的socket

——有感於實際程式設計和開源專案研究。

        我們深諳資訊交流的價值,那網路中程式之間如何通訊,如我們每天開啟瀏覽器瀏覽網頁時,瀏覽器的程式怎麼與web伺服器通訊的?當你用QQ聊天時,QQ程式怎麼與伺服器或你好友所在的QQ程式通訊?這些都得靠socket?那什麼是socket?socket的型別有哪些?還有socket的基本函式,這些都是本文想介紹的。本文的主要內容如下:

  • 1、網路中程式之間如何通訊?
  • 2、Socket是什麼?
  • 3、socket的基本操作
    • 3.1、socket()函式
    • 3.2、bind()函式
    • 3.3、listen()、connect()函式
    • 3.4、accept()函式
    • 3.5、read()、write()函式等
    • 3.6、close()函式
  • 4、socket中TCP的三次握手建立連線詳解
  • 5、socket中TCP的四次握手釋放連線詳解
  • 6、一個例子(實踐一下)
  • 7、留下一個問題,歡迎大家回帖回答!!!

1、網路中程式之間如何通訊?

本地的程式間通訊(IPC)有很多種方式,但可以總結為下面4類:

  • 訊息傳遞(管道、FIFO、訊息佇列)
  • 同步(互斥量、條件變數、讀寫鎖、檔案和寫記錄鎖、訊號量)
  • 共享記憶體(匿名的和具名的)
  • 遠端過程呼叫(Solaris門和Sun RPC)

但這些都不是本文的主題!我們要討論的是網路中程式之間如何通訊?首要解決的問題是如何唯一標識一個程式,否則通訊無從談起!在本地可以通過程式PID來唯一標識一個程式,但是在網路中這是行不通的。其實TCP/IP協議族已經幫我們解決了這個問題,網路層的“ip地址”可以唯一標識網路中的主機,而傳輸層的“協議+埠可以唯一標識主機中的應用程式(程式)。這樣利用三元組(ip地址,協議,埠)就可以標識網路的程式了,網路中的程式通訊就可以利用這個標誌與其它程式進行互動。

使用TCP/IP協議的應用程式通常採用應用程式設計介面UNIX  BSD的套接字(socket)和UNIX System V的TLI(已經被淘汰),來實現網路程式之間的通訊。就目前而言,幾乎所有的應用程式都是採用socket,而現在又是網路時代,網路中程式通訊是無處不在,這就是我為什麼說“一切皆socket”。

2、什麼是Socket?

上面我們已經知道網路中的程式是通過socket來通訊的,那什麼是socket呢?socket起源於Unix,而Unix/Linux基本哲學之一就是“一切皆檔案”,都可以用“開啟open –> 讀寫write/read –> 關閉close”模式來操作。我的理解就是Socket就是該模式的一個實現,socket即是一種特殊的檔案,一些socket函式就是對其進行的操作(讀/寫IO、開啟、關閉),這些函式我們在後面進行介紹。

socket一詞的起源

在組網領域的首次使用是在1970年2月12日釋出的文獻IETF RFC33中發現的,撰寫者為Stephen Carr、Steve Crocker和Vint Cerf。根據美國計算機歷史博物館的記載,Croker寫道:“名稱空間的元素都可稱為套接字介面。一個套接字介面構成一個連線的一端,而一個連線可完全由一對套接字介面規定。”計算機歷史博物館補充道:“這比BSD的套接字介面定義早了大約12年。”

3、socket的基本操作

既然socket是“open—write/read—close”模式的一種實現,那麼socket就提供了這些操作對應的函式介面。下面以TCP為例,介紹幾個基本的socket介面函式。


相關文章