web開發 php之 socket(TCP/IP)原理

   有不對的地方歡迎大家來指正交流

   我們平時瀏覽網頁是這樣的 :瀏覽器輸入網址,請求服務器,服務器響應請求返回內容給瀏覽器,瀏覽器通過渲染之後就是我們看到的漂亮的網頁內容.

    做爲web開發者都知道,瀏覽器和服務器是通過使用HTTP協議完成從客戶端請求到服務器響應等一系列運作流程,而HTTP協議是建立在TCP/IP協議族之上的應用層協議。計算機和網絡設備通信其實是通過TCP/IP協議族。

     SOCKET

     就是對TCP/IP的封裝。可以理解爲就像php中的面向對像中的類是對對象的一種描述差不多。那麼瞭解socket之前先對tcp/ip簡單瞭解。

    TCP/IP

      百度上是這樣解釋TCP/IP

      Transmission Control Protocol/Internet Protocol的簡寫,中譯名爲傳輸控制協議/因特網互聯協議,又名網絡通訊協議,是Internet最基本的協議、Internet國際互聯網絡的基礎,由網絡層的IP協議和傳輸層的TCP協議組成。TCP/IP 定義了電子設備如何連入因特網,以及數據如何在它們之間傳輸的標準  。TCP是面向連接的通信協議,通過三次握手建立連接,通訊完成時要拆除連接,用於端到端的通訊。
    可能都知道ISO七層模型,其實就是個定義了一套用於計算機或通信系統間互聯的標準體系,就是一種通信標準。如下圖:

    

   我們可以看到 HTTP屬於應用層,TCP屬於傳輸層他能保障網絡間數據傳輸的完整性和準確性,有興趣的可以自行深入學習。

   進程

   我們知道大多數操作系統都支持多程序同時運行,可以理解爲各個運行的程序就是(進程).
   同一主機,不同進程都有一個唯一的進程號(PID)來標識,用於進程之間的通信。網絡通訊就不能這樣幹了,要是用PID來標識網絡進程的話,就有可能PID就重複了,那就亂了。就比如你本來要和叫A的通話,結果還有一個叫A的,你先喊一聲誰是A,結果第一個A睡着了,第二個A應答你了,於是你就吧你的小祕密告訴第二個A了,這就尷尬了。。

    我們知道IP層的ip地址可以唯一標識主機,而TCP層協議和端口號可以唯一標識主機的一個進程,這樣就可以利用ip地址+協議+端口號來唯一標識網絡中的一個進程。

    前面說了SOCKET是對tcp/ip的抽象,因此我們可以用SOCKET來實現網絡間進程通信。圖如下:

   

     打破砂鍋問到底,因此瞭解SOCKET通信之前,先簡單瞭解一下TCP/ip通信流程.

     資源參考:http://www.2cto.com/net/201310/251896.html

     tcp/ip網絡通信流程圖解:

    

   可以看出分爲三步:建立連接、傳輸數據、斷開連接

     注意:確認方Ack=發起方seq+1,兩端配對這就是其中的套路
   建立連接:

        1.客戶端發送 SYN包 sep=x 到服務器

         2.server 端 收到SYN包後 會向客戶端發送 ACK包和SYN包,告訴客戶端已經接受到消息

        3.客戶端接收到 服務端 的ACK+SYN包後再次向服務端發送ACK包,此時完成鏈接

     傳輸數據:

        client發送的包都有相應的seq編號,server收到數據後,會回覆ack進行確認,表示數據已經收到

      斷開連接 

        1.client發送一個FIN,用來關閉數據傳送

        2.server收到FIN包後,發送一個ACK給client表示確認

        3.server發送一個FIN,關閉兩者間的數據傳送

        4.client收到FIN後發送ACK給server確認,此時斷開連接

     接下來SOCKET:
     
    其實上面已經把原理知道了,socket就是用來操作TCP的
          再次回顧請求流程以瀏覽網頁爲例:

              1.建立鏈接後(俗稱三次握手)  通過HTTP協議 向server端口發起請求、

              2.server接受並確認請求 ,響應內容通過HTTP給client

              3.關閉鏈接(俗稱四次握手)

          

         SOCKET通訊流程圖:

           

server端:       
             步驟上圖已經很明確了:

                     1.創建流式套接字(TCP)   //什麼是套接字請自行查閱資料

                     2.  套接字綁定本地地址和server端口

                     3. 監聽連接請求

                      4.接受一個新連接,最終返回新的套接字

                相關函數查詢php手冊:http://php.net/manual/zh/function.socket-create.php    

    resource socket_create ( int $domain , int $type , int $protocol ) //創建一個套接字(通訊節點)  
    bool socket_bind ( resource $socket , string $address [, int $port = 0 ] )// 給套接字綁定名字(爲server端綁定IP和端口)  
    bool socket_listen ( resource $socket [, int $backlog = 0 ] )//監聽套接字上的連接(爲client向server端口發起連接,俗稱三次握手)
    resource socket_accept ( resource $socket )//接受套接字上的連接(它接收連接請求並調用一個子連接Socket來處理客戶端和服務器間的信息)
    string socket_read ( resource $socket , int $length [, int $type = PHP_BINARY_READ ] )//從套接字讀取最大長度字節數(讀取客戶端發送數據流)
    int socket_write ( resource $socket , string $buffer [, int $length ] ) //寫入套接字(數據傳送:向client端)  
     void socket_close    ( resource $socket   )//  關閉套接字資源  (如果要繼續監聽的話只需關閉子連接)

 

 

客戶端:

 

      1.創建流式套接字(TCP) 

       2. 利用返回的資源與server端建立連接

 

     resource socket_create ( int $domain , int $type , int $protocol ) //創建一個套接字(通訊節點)
     bool socket_connect    ( resource $socket   , string $address   [, int $port = 0  ] )//開啓一個套接字連接 裏頭已經有了目的地址和端口
     socket_write($socket, "hello socket") //向server發送數據

      int socket_write    ( resource $socket   , string $buffer   [, int $length  ] )//數據傳送 向server端
      void socket_close    ( resource $socket   )//  關閉套接字資源。

 

關於應用:
   SOCKET 是通常應用於網絡通訊,現在HTML5的websocket越來越成熟,可以用來在網頁與SOCKET通訊就像打電話一樣雙方都能互相傳達信息,
   所以可以做一個網絡聊天室來玩玩大笑,是不是很神奇大笑

很簡單,就這些,前提是要把TCP/IP搞明白

下一篇寫應用層協議:HTTP詳解

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章