從零帶你入門Socket編程

相信大部分的初中級PHP程序員平時寫的業務代碼佔絕大多數,寫厭了平時的增刪改查,何不體驗體驗網絡編程的魅力呢。php

學習網絡編程可以很好的理解一些底層的網絡通訊,好比Apache、Nginx如何接受HTTP請求的,而後又是如何和PHP來進行交互的。Nginx爲何能處理高併發的請求?常聽別人說的同步IO、異步IO、阻塞IO、非阻塞IO…等等究竟是什麼意思?相信你學習了網絡編程以後就會對其有深入的理解。固然本文只是一個socket編程的入門,暫時是不包括以上內容的。程序員

應該有一部分同窗是沒有接觸過網絡編程的,在這裏首先介紹一下網絡編程是什麼意思。web

網絡編程就是如何在程序中實現兩臺計算機的通訊。而網絡編程最終要開發出來的應用大多數爲支持各類協議的服務器,好比:http服務器、websocket服務器、或者是基於自定義的協議實現的服務。其本質上是基於socket套接字,套接字把TCP的通訊機制在內部已經實現了,開發人員只注重編碼就好了。至於爲何叫套接字,這裏我就不講述了。編程

在開始編碼以前,首先介紹一下TCP協議棧:
圖片描述服務器

上圖是我從《TCP/IP網絡編程》這本書拍下來的。websocket

TCP/IP協議棧的誕生起源於一個問題:如何經過因特網完成數據的有效傳輸?網絡

因此基於這個問題,硬件、系統、路由等各個領域的專家彙集在一塊兒,最終定義出了多套大大小小的協議。而咱們要講解的TCP/IP協議,則是處於傳輸層的。併發

下面是TCP協議在數據傳輸方面的簡單圖示:異步

圖片描述

上面的圖中,主機A向主機B發送數據時,主機A必須在接收到主機B返回的確認消息後,才發送下一個數據包。經過上圖咱們不難看出TCP協議的最終目的就是:保證數據傳輸的有效性。對於初學者,咱們暫時只需記住以上結論便可。socket

下面主要介紹PHPsocket開發所要使用的一些標準函數和其用法,最終編寫出一個能夠向客戶端發送「hello,socket」的程序。

建立一個在本機端口監聽的套接字須要四個步驟:

1.建立套接字

2.爲這個套接字分配IP和端口號

3.使此套接字轉換爲可接受請求狀態

4.開始受理請求

接下來介紹PHP完成這些步驟所須要的函數:

socket_create 建立套接字

socket_bind 分配IP和端口

socket_listen 監聽鏈接

socket_accept 受理鏈接

socket_connect 鏈接一個套接字

socket_write 寫入數據到套接字

socket_read 從套接字讀取最大長度字節數

咱們暫時只需知道這個函數是作什麼的就好了,至於詳細的參數含義能夠等作完下面的例子以後在去PHP官網查看。

接下將是最重要的編碼環節:

如下server.php爲服務端的代碼:
圖片描述

代碼解讀:

第一處:建立一個套接字而且使用IPV4協議,至於參數什麼意思相信各位具備查閱文檔的能力

第二處:將該套接字綁定到本機的8899端口

第三處:調用 socket_listen 開始監聽此端口的請求

第四處:開始受理鏈接請求,這裏要注意一下,若是沒有接收到請求的話,此函數會一直阻塞

第五到第七處:向發送請求的客戶端發送「hello,socket」字符串,最後必定注意關閉socket資源

咱們運行一下這個文件:

輸入:php server.php

按下回車以後咱們會看到此腳本已經進入阻塞狀態:
圖片描述

到這裏咱們最基本的一個服務端程序已經完成了,這裏可能會有小夥伴有疑問了,以上第四處究竟是受理的什麼請求呢?

那麼接下來所要編寫的客戶端程序則是這個問題的最好解答。

客戶端程序相對來講比較簡單一點:

分爲兩步:

1.建立用於向服務端指定端口發送請求的套接字

2.經過調用鏈接函數向服務端發送鏈接請求

下面開始客戶端client.php的編寫:

圖片描述

代碼解讀:

第一處:鏈接到以上服務端程序所監聽的8899端口

第二處:接收服務端發來的「hello,socket」消息

第三處:輸出接收到的字符

接下來咱們先運行服務端:

php server.php

而後再運行客戶端:

php client.php

將看到以下結果:
圖片描述

成功的輸出了「hello,socket」字符串!

相信你們看到這裏已經對socket編程有一個初步的認識。

接下來介紹幾個函數能夠很方便的完成以上操做:

對於以上的服務端程序咱們可使用stream_socket_server 函數來改寫的更爲簡潔,使用stream_socket_server函數咱們能夠一次性的建立、綁定、監聽三個步驟。

如下是修改過的server_v2.php
圖片描述

代碼解答:

第一處:使用stream_socket_server 一次性建立套接字,綁定到8899端口,開始監聽 三個步驟。

第二處:因爲是用stream_socket_server函數建立的資源,與socket_create建立的資源不一樣,因此這裏所有使用操做stream資源的函數。

關於phpSocket編程的入門,就先介紹到這裏,若有錯誤的地方歡迎後臺回覆指出哦。

若是以爲本文不錯的話,能夠關注個人公衆號: 阿毛的Coding之路

相關文章
相關標籤/搜索