當前位置:編程學習大全網 - 編程語言 - socket在php主要是什麽作用?用在哪些方面?

socket在php主要是什麽作用?用在哪些方面?

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

產生壹個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。

<?php

$commonProtocol = getprotobyname(“tcp”);

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

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

socket_listen($socket);

// More socket functionality to come

>

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

$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

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

<?php

if(!extension_loaded(‘sockets’))

{

if(strtoupper(substr(PHP_OS, 3)) == “WIN”)

{

dl(‘php_sockets.dll’);

}

else

{

dl(‘sockets.so’);

}

}

>

如果妳不知道妳的socket是否打開,那麽妳可以使用phpinfo()函數來確定socket是否打開。妳通過查看phpinfo信息了解socket是否打開。如下圖:

查看phpinfo()關於socket的信息

◆ 產生壹個服務器

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

<?php

$commonProtocol = getprotobyname("tcp");

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

socket_bind($socket, 'localhost', 1337);

socket_listen($socket);

// Accept any incoming connections to the server

$connection = socket_accept($socket);

if($connection)

{

socket_write($connection, "You have connected to the socket.../n/r");

}

>

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

set_time_limit(0);

在妳的命令提示符中對這個腳本進行簡單測試:

Php.exe example01_server.php

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

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

這個第壹個問題比較容易解決,妳可以使用壹個應用程序去每次都連接到服務器。但是後面的問題是妳需要使用壹個Web頁面去連接這個服務器,這個比較困難。妳可以讓妳的服務器接受連接,然後些數據到客戶端(如果它壹定要寫的話),關閉連接並且等待下壹個連接。

在上壹個代碼的基礎上再改進,產生下面的代碼來做妳的新服務器端:

<?php

// Set up our socket

$commonProtocol = getprotobyname("tcp");

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

socket_bind($socket, 'localhost', 1337);

socket_listen($socket);

// Initialize the buffer

$buffer = "NO DATA";

while(true)

{

// Accept any connections coming in on this socket

$connection = socket_accept($socket);

printf("Socket connected/r/n");

// Check to see if there is anything in the buffer

if($buffer != "")

{

printf("Something is in the buffer...sending data.../r/n");

socket_write($connection, $buffer . "/r/n");

printf("Wrote to socket/r/n");

}

else

{

printf("No Data in the buffer/r/n");

}

// Get the input

while($data = socket_read($connection, 1024, PHP_NORMAL_READ))

{

$buffer = $data;

socket_write($connection, "Information Received/r/n");

printf("Buffer: " . $buffer . "/r/n");

}

socket_close($connection);

printf("Closed the socket/r/n/r/n");

}

>

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

This is what the server does. It initializes the socket and the buffer that you use to receive

and send data. Then it waits for a connection. Once a connection is created it prints

“Socket connected” to the screen the server is running on. The server then checks to see if

there is anything in the buffer; if there is, it sends the data to the connected computer.

After it sends the data it waits to receive information. Once it receives information it stores

it in the data, lets the connected computer know that it has received the information, and

then closes the connection. After the connection is closed, the server starts the whole

process again.

◆ 產生壹個客戶端

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

To solve the second problem is very easy. You need to create a PHP page that connects to

a socket, receive any data that is in the buffer, and process it. After you have processed the

data in the buffer you can send your data to the server. When another client connects, it

will process the data you sent and the client will send more data back to the server.

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

<?php

// Create the socket and connect

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

$connection = socket_connect($socket,’localhost’, 1337);

while($buffer = socket_read($socket, 1024, PHP_NORMAL_READ))

{

if($buffer == “NO DATA”)

{

echo(“<p>NO DATA</p>”);

break;

}

else

{

// Do something with the data in the buffer

echo(“<p>Buffer Data: “ . $buffer . “</p>”);

}

}

echo(“<p>Writing to Socket</p>”);

// Write some test data to our socket

if(!socket_write($socket, “SOME DATA/r/n”))

{

echo(“<p>Write failed</p>”);

}

// Read any response from the socket

while($buffer = socket_read($socket, 1024, PHP_NORMAL_READ))

{

echo(“<p>Data sent was: SOME DATA<br> Response was:” . $buffer . “</p>”);

}

echo(“<p>Done Reading from Socket</p>”);

>

這個例子的代碼演示了客戶端連接到服務器。客戶端讀取數據。如果這是第壹時間到達這個循環的首次連接,這個服務器將發送“NO DATA”返回給客戶端。如果情況發生了,這個客戶端在連接之上。客戶端發送它的數據到服務器,數據發送給服務器,客戶端等待響應。壹旦接受到響應,那麽它將把響應寫到屏幕上。

  • 上一篇:誰可以給我好的開頭和結尾各10句,3對首尾呼應。都不要太長!但是要快,急!!!!
  • 下一篇:金碟的數據庫的修改
  • copyright 2024編程學習大全網