亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > PHP > 正文

php socket講解與實例

2024-05-04 21:47:25
字體:
來源:轉載
供稿:網友

在這一章里你將了解到迷人而又讓人容易糊涂的套接字(Sockets),Sockets在PHP中是沒有充分利用的功能,今天你將看到產生一個能使用客戶端連接的服務器,并在客戶端使用socket進行連接,服務器端將詳細的處理信息發送給客戶端。

當你看到完整的socket過程,那么你將會在以后的程序開發中使用它。這個服務器是一個能讓你連接的HTTP服務器,客戶端是一個Web瀏覽器,這是一個單一的 客戶端/服務器 的關系。

Socket 基礎

PHP使用Berkley的socket庫來創建它的連接。你可以知道socket只不過是一個數據結構。你使用這個socket數據結構去開始一個客戶端和服務器之間的會話。這個服務器是一直在監聽準備產生一個新的會話。當一個客戶端連接服務器,它就打開服務器正在進行監聽的一個端口進行會話。這時,服務器端接受客戶端的連接請求,那么就進行一次循環?,F在這個客戶端就能夠發送信息到服務器,服務器也能發送信息給客戶端。

產生一個Socket,你需要三個變量:一個協議、一個socket類型和一個公共協議類型,產生一個socket有三種協議供選擇,繼續看下面的內容來獲取詳細的協議內容。

定義一個公共的協議類型是進行連接一個必不可少的元素。下面的表我們看看有那些公共的協議類型。

表一:協議

名字/常量  描述

AF_INET  這是大多數用來產生socket的協議,使用TCP或UDP來傳輸,用在IPv4的地址

AF_INET6     與上面類似,不過是來用在IPv6的地址

AF_UNIX  本地協議,使用在Unix和Linux系統上,它很少使用,一般都是當客戶端和服務器在同一臺及其上的時候使用

表二:Socket類型

名字/常量  描述

SOCK_STREAM  這個協議是按照順序的、可靠的、數據完整的基于字節流的連接。這是一個使用最多的socket類型,這個socket是使用TCP來進行傳輸。

SOCK_DGRAM  這個協議是無連接的、固定長度的傳輸調用。該協議是不可靠的,使用UDP來進行它的連接。

SOCK_SEQPACKET  這個協議是雙線路的、可靠的連接,發送固定長度的數據包進行傳輸。必須把這個包完整的接受才能進行讀取。

SOCK_RAW  這個socket類型提供單一的網絡訪問,這個socket類型使用ICMP公共協議。(ping、traceroute使用該協議)

SOCK_RDM  這個類型是很少使用的,在大部分的操作系統上沒有實現,它是提供給數據鏈路層使用,不保證數據包的順序

表三:公共協議

名字/常量   描述

ICMP  互聯網控制消息協議,主要使用在網關和主機上,用來檢查網絡狀況和報告錯誤信息

UDP  用戶數據報文協議,它是一個無連接,不可靠的傳輸協議

TCP 傳輸控制協議,這是一個使用最多的可靠的公共協議,它能保證數據包能夠到達接受者那兒,如果在傳輸過程中發生錯誤,那么它將重新發送出錯數據包。

現在你知道了產生一個socket的三個元素,那么我們就在php中使用socket_create()函數來產生一個socket。這個socket_create()函數需要三個參數:一個協議、一個socket類型、一個公共協議。socket_create()函數運行成功返回一個包含socket的資源類型,如果沒有成功則返回false。

Resourece socket_create(int protocol, int socketType, int commonProtocol);

現在你產生一個socket,然后呢?php提供了幾個操縱socket的函數。你能夠綁定socket到一個IP,監聽一個socket的通信,接受一個socket;現在我們來看一個例子,了解函數是如何產生、接受和監聽一個socket。

  1. <?php 
  2. $commonProtocol = getprotobyname(“tcp”); 
  3. $socket = socket_create(AF_INET, SOCK_STREAM, $commonProtocol); 
  4. socket_bind($socket, ‘localhost’, 1337); 
  5. socket_listen($socket); 
  6. // More socket functionality to come 
  7. ?> 

上面這個例子產生一個你自己的服務器端。例子第一行,

$commonProtocol = getprotobyname(“tcp”);

使用公共協議名字來獲取一個協議類型。在這里使用的是TCP公共協議,如果你想使用UDP或者ICMP協議,那么你應該把getprotobyname()函數的參數改為“udp”或“icmp”。還有一個可選的辦法是不使用getprotobyname()函數而是指定SOL_TCP或SOL_UDP在socket_create()函數中。

$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);

例子的第二行是產生一個socket并且返回一個socket資源的實例。在你有了一個socket資源的實例以后,你就必須把socket綁定到一個IP地址和某一個端口上。

socket_bind($socket, ‘localhost’, 1337);

在這里你綁定socket到本地計算機(127.0.0.1)和綁定socket到你的1337端口。然后你就需要監聽所有進來的socket連接。

socket_listen($socket);

在第四行以后,你就需要了解所有的socket函數和他們的使用。

表四:Socket函數

函數名  描述

socket_accept()    接受一個Socket連接

socket_bind()     把socket綁定在一個IP地址和端口上

socket_clear_error()   清除socket的錯誤或者最后的錯誤代碼

socket_close()     關閉一個socket資源

socket_connect()    開始一個socket連接

socket_create_listen()   在指定端口打開一個socket監聽

socket_create_pair()   產生一對沒有區別的socket到一個數組里

socket_create()    產生一個socket,相當于產生一個socket的數據結構

socket_get_option()    獲取socket選項

socket_getpeername()   獲取遠程類似主機的ip地址

socket_getsockname()   獲取本地socket的ip地址

socket_iovec_add()    添加一個新的向量到一個分散/聚合的數組

socket_iovec_alloc()   這個函數創建一個能夠發送接收讀寫的iovec數據結構

socket_iovec_delete()   刪除一個已經分配的iovec

socket_iovec_fetch()   返回指定的iovec資源的數據

socket_iovec_free()    釋放一個iovec資源

socket_iovec_set()    設置iovec的數據新值

socket_last_error()    獲取當前socket的最后錯誤代碼

socket_listen()     監聽由指定socket的所有連接

socket_read()     讀取指定長度的數據

socket_readv()     讀取從分散/聚合數組過來的數據

socket_recv()     從socket里結束數據到緩存

socket_recvfrom()    接受數據從指定的socket,如果沒有指定則默認當前socket

socket_recvmsg()    從iovec里接受消息

socket_select()     多路選擇

socket_send()     這個函數發送數據到已連接的socket

socket_sendmsg()    發送消息到socket

socket_sendto()    發送消息到指定地址的socket

socket_set_block()    在socket里設置為塊模式

socket_set_nonblock()   socket里設置為非塊模式

socket_set_option()    設置socket選項

socket_shutdown()    這個函數允許你關閉讀、寫、或者指定的socket

socket_strerror()    返回指定錯誤號的詳細錯誤

socket_write()     寫數據到socket緩存

socket_writev()    寫數據到分散/聚合數組

(注: 函數介紹刪減了部分原文內容,函數詳細使用建議參考英文原文,或者參考PHP手冊)

以上所有的函數都是PHP中關于socket的,使用這些函數,你必須把你的socket打開,如果你沒有打開,請編輯你的php.ini文件,去掉下面這行前面的注釋:

extension=php_sockets.dll

如果你無法去掉注釋,那么請使用下面的代碼來加載擴展庫:

  1. <?php  
  2. if(!extension_loaded(‘sockets’))  
  3. {  
  4. if(strtoupper(substr(PHP_OS, 3)) == “WIN”)  
  5. {  
  6. dl(‘php_sockets.dll’); 
  7. else 
  8. dl(‘sockets.so’);  
  9. }  
  10. }  
  11. ?> 
如果你不知道你的socket是否打開,那么你可以使用phpinfo()函數來確定socket是否打開。你通過查看phpinfo信息了解socket是否打開,查看phpinfo()關于socket的信息.

產生一個服務器

現在我們把第一個例子進行完善。你需要監聽一個指定的socket并且處理用戶的連接。

  1. <?php 
  2. $commonProtocol = getprotobyname("tcp"); 
  3. $socket = socket_create(AF_INET, SOCK_STREAM, $commonProtocol); 
  4. socket_bind($socket'localhost', 1337); 
  5. socket_listen($socket); 
  6. // Accept any incoming connections to the server 
  7. $connection = socket_accept($socket); 
  8. if($connection
  9.  socket_write($connection"You have connected to the socket.../n/r");  
  10. }  
  11. ?> 

你應該使用你的命令提示符來運行這個例子。理由是因為這里將產生一個服務器,而不是一個Web頁面。如果你嘗試使用Web瀏覽器來運行這個腳本,那么很有可能它會超過30秒的限時。你可以使用下面的代碼來設置一個無限的運行時間,但是還是建議使用命令提示符來運行。

set_time_limit(0);

在你的命令提示符中對這個腳本進行簡單測試:Php.exe example01_server.php

如果你沒有在系統的環境變量中設置php解釋器的路徑,那么你將需要給php.exe指定詳細的路徑。當你運行這個服務器端的時候,你能夠通過遠程登陸(telnet)的方式連接到端口1337來測試這個服務器。

上面的服務器端有三個問題:1. 它不能接受多個連接。2. 它只完成唯一的一個命令。3. 你不能通過Web瀏覽器連接這個服務器。

這個第一個問題比較容易解決,你可以使用一個應用程序去每次都連接到服務器。但是后面的問題是你需要使用一個Web頁面去連接這個服務器,這個比較困難。你可以讓你的服務器接受連接,然后些數據到客戶端(如果它一定要寫的話),關閉連接并且等待下一個連接,在上一個代碼的基礎上再改進,產生下面的代碼來做你的新服務器端:

  1. <?php  
  2. // Set up our socket  
  3. $commonProtocol = getprotobyname("tcp");  
  4. $socket = socket_create(AF_INET, SOCK_STREAM, $commonProtocol);  
  5. socket_bind($socket'localhost', 1337);  
  6. socket_listen($socket);  
  7. // Initialize the buffer  
  8. $buffer = "NO DATA";  
  9. while(true)  
  10. {  
  11.  // Accept any connections coming in on this socket 
  12.  $connection = socket_accept($socket); 
  13.  printf("Socket connected/r/n"); 
  14.  // Check to see if there is anything in the buffer 
  15.  if($buffer != ""
  16.  { 
  17.   printf("Something is in the buffer...sending data.../r/n");  
  18.   socket_write($connection$buffer . "/r/n");  
  19.   printf("Wrote to socket/r/n"); 
  20.  } 
  21.  else  
  22.  {  
  23.   printf("No Data in the buffer/r/n"); 
  24.  } 
  25.  // Get the input 
  26.  while($data = socket_read($connection, 1024, PHP_NORMAL_READ)) 
  27.  { 
  28.   $buffer = $data;  
  29.   socket_write($connection"Information Received/r/n");  
  30.   printf("Buffer: " . $buffer . "/r/n");  
  31.  }  
  32.  socket_close($connection);  
  33.  printf("Closed the socket/r/n/r/n");  
  34. }  
  35. ?> 

這個服務器端要做什么呢?它初始化一個socket并且打開一個緩存收發數據。它等待連接,一旦產生一個連接,它將打印“Socket connected”在服務器端的屏幕上。這個服務器檢查緩沖區,如果緩沖區里有數據,它將把數據發送到連接過來的計算機。然后它發送這個數據的接受信息,一旦它接受了信息,就把信息保存到數據里,并且讓連接的計算機知道這些信息,最后關閉連接。當連接關閉后,服務器又開始處理下一次連接。

產生一個客戶端

處理第二個問題是很容易的。你需要產生一個php頁連接一個socket,發送一些數據進它的緩存并處理它。然后你又個處理后的數據在還頓,你能夠發送你的數據到服務器。在另外一臺客戶端連接,它將處理那些數據。

下面的例子示范了使用socket:

  1. <?php  
  2. // Create the socket and connect  
  3. $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);  
  4. $connection = socket_connect($socket,’localhost’, 1337);  
  5. while($buffer = socket_read($socket, 1024, PHP_NORMAL_READ))  
  6. {  
  7.  if($buffer == “NO DATA”)  
  8.  {  
  9.  echo(“<p>NO DATA</p>”);  
  10.  break
  11.  } 
  12.  else 
  13.  { 
  14.   // Do something with the data in the buffer  
  15.   echo(“<p>Buffer Data: “ . $buffer . “</p>”);  
  16.  }  
  17. }  
  18. echo(“<p>Writing to Socket</p>”); 
  19. // Write some test data to our socket 
  20. if(!socket_write($socket, “SOME DATA/r/n”)) 
  21.  echo(“<p>Write failed</p>”);  
  22. }  
  23. // Read any response from the socket 
  24. while($buffer = socket_read($socket, 1024, PHP_NORMAL_READ)) 
  25.  echo(“<p>Data sent was: SOME DATA<br> Response was:” . $buffer . “</p>”);  
  26. }  
  27. echo(“<p>Done Reading from Socket</p>”);  
  28. ?> 

這個例子的代碼演示了客戶端連接到服務器??蛻舳俗x取數據。如果這是第一時間到達這個循環的首次連接,這個服務器將發送“NO DATA”返回給客戶端。如果情況發生了,這個客戶端在連接之上??蛻舳税l送它的數據到服務器,數據發送給服務器,客戶端等待響應。一旦接受到響應,那么它將把響應寫到屏幕上,結合Socket的坦克大戰,因為是描述游戲和socket結合,跟本文聯系不大,所以不翻譯,建議參考英文原文.

題外話:翻譯文章的初衷是因為我個人對socket非常感興趣,而且目前國內見php的文章比較少,除了php手冊里面的部分內容,所以在我看了《PHP Game Programming》這本書里有關于socket的內容后毅然決定要翻譯,我知道翻譯出來的質量不行,還請見諒。

另外,我在《Core PHP Programming》Third Edition中也發現里面的Socket內容講的不錯,如果有空,我想也許我會把它也給翻譯一下。這是我第一次翻譯文章,花了我近五個小時,文章可以說是錯誤百出,如果翻譯的不合理請見諒,如果有興趣提高這個內容可以給我發郵件。這個凌晨時分,竟然無法入眠,不知道是不是在其他角落,也有人同我一樣。

希望本文能夠給向學習PHP Socket編程的朋友一點幫助,感謝你閱讀這個錯誤百出的文章

上一篇:php模板

下一篇:使用XML-RPC構造WebService

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美性猛交丰臀xxxxx网站| 欧美裸身视频免费观看| 日韩精品在线第一页| www.亚洲人.com| 91精品在线播放| 亚洲国产欧美一区二区三区久久| 欧美巨大黑人极品精男| 欧美国产精品人人做人人爱| 九色成人免费视频| 欧美日韩成人免费| 亚洲free性xxxx护士hd| 欧美壮男野外gaytube| www.亚洲一二| 久久人91精品久久久久久不卡| 国产精品男人爽免费视频1| 日本在线观看天堂男亚洲| 日本不卡高字幕在线2019| 亚洲免费av片| 久久久久久免费精品| 国产在线拍偷自揄拍精品| 中文精品99久久国产香蕉| 国产精品电影久久久久电影网| 日韩免费在线观看视频| 亚洲一区二区久久| 成人444kkkk在线观看| 精品国产成人在线| 亚洲欧美在线x视频| 久久久久久有精品国产| 亚洲国产女人aaa毛片在线| 91午夜在线播放| 91精品国产91久久久久福利| 国产精品香蕉av| 亚洲自拍小视频免费观看| 精品美女国产在线| 久久91亚洲精品中文字幕| 正在播放欧美一区| 亚洲va男人天堂| 国产在线精品一区免费香蕉| 欧美在线不卡区| 亚洲专区国产精品| 亚洲电影免费在线观看| 精品久久久久久久久中文字幕| 中文字幕一区日韩电影| 亚洲国模精品私拍| 亚洲女人天堂色在线7777| 美女av一区二区三区| 国产欧美一区二区三区在线| 欧美日韩第一视频| 日本国产一区二区三区| 久久九九国产精品怡红院| 欧美区在线播放| 欧美日本国产在线| 影音先锋欧美精品| 69久久夜色精品国产7777| 国产精品你懂得| 最近2019年中文视频免费在线观看| 欧美老少做受xxxx高潮| 成人疯狂猛交xxx| 久久艳片www.17c.com| 国产91精品久久久| 日韩av免费观影| 欧美裸体xxxxx| 亚洲一区亚洲二区| 欧美电影在线观看网站| 中文字幕亚洲欧美日韩在线不卡| 午夜精品久久久久久久99热| 精品视频在线导航| 精品无人区太爽高潮在线播放| 日韩有码片在线观看| 精品国产91久久久久久| 欧美成人中文字幕在线| 国产精品免费小视频| 亚洲欧美另类人妖| 欧亚精品在线观看| 成人精品在线观看| 久久6免费高清热精品| 亚洲视频欧洲视频| 欧洲成人在线观看| 久久精品人人做人人爽| 性欧美激情精品| 欧美高清视频在线播放| 精品毛片三在线观看| 欧美高清视频在线观看| 国产脚交av在线一区二区| 91精品久久久久久久久久久久久| 久久久久久久久电影| 欧美日韩视频在线| 亚洲午夜精品久久久久久久久久久久| 亚洲自拍偷拍一区| 久久久亚洲国产天美传媒修理工| 日韩久久精品电影| 揄拍成人国产精品视频| 亚洲一区二区三区乱码aⅴ| 38少妇精品导航| 亚洲色图第三页| 浅井舞香一区二区| 欧美激情喷水视频| 日本国产一区二区三区| 欧美成人手机在线| 欧美大人香蕉在线| 日韩理论片久久| 国产欧美日韩精品丝袜高跟鞋| 91久久久久久久久| 在线精品国产成人综合| 国产亚洲精品久久久久久牛牛| 美女少妇精品视频| 精品网站999www| 欧美理论电影在线播放| 亚洲电影免费观看高清| 欧美精品一区二区免费| 亚洲a一级视频| 欧美精品做受xxx性少妇| 久久久久成人精品| 亚洲xxxxx| 欧美福利在线观看| 久久久视频免费观看| 国产精品91久久| 亚洲福利视频在线| 18一19gay欧美视频网站| 久久99精品久久久久久青青91| 欧美大尺度在线观看| 黄色成人av网| 成人精品一区二区三区电影免费| 亚洲国产成人在线视频| 神马久久桃色视频| 国产精品嫩草影院一区二区| 久久夜精品va视频免费观看| 欧美情侣性视频| 亚洲视屏在线播放| 日产精品久久久一区二区福利| 成人中文字幕+乱码+中文字幕| 国产精品伦子伦免费视频| 日韩不卡在线观看| 亚洲精品国产美女| 亚洲欧美在线第一页| 国产成人精品视| 日韩福利在线播放| 国产日韩精品综合网站| 国产精品久久久久久久久男| 一本色道久久88亚洲综合88| 久久久久国产精品免费网站| 自拍偷拍免费精品| 欧美专区日韩视频| 欧美日韩精品在线播放| 久久韩剧网电视剧| 日本欧美黄网站| 色偷偷偷综合中文字幕;dd| 国产成人在线视频| 久久久久国产精品免费网站| 色天天综合狠狠色| 日本欧美黄网站| 亚洲欧美成人一区二区在线电影| 国产精品福利小视频| 亚洲图片制服诱惑| 自拍偷拍亚洲精品| 国产精品欧美激情| 欧美国产日本在线| 欧美国产精品va在线观看| 欧美精品18videosex性欧美| 欧美色图在线视频| 亚洲天堂精品在线| 一个人看的www欧美| 成人黄色在线观看| 操人视频在线观看欧美|