溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

php怎么實現(xiàn)簡單的socket服務(wù)器客戶端

發(fā)布時間:2021-09-04 17:44:21 來源:億速云 閱讀:153 作者:chen 欄目:開發(fā)技術(shù)

這篇文章主要介紹“php怎么實現(xiàn)簡單的socket服務(wù)器客戶端”,在日常操作中,相信很多人在php怎么實現(xiàn)簡單的socket服務(wù)器客戶端問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”php怎么實現(xiàn)簡單的socket服務(wù)器客戶端”的疑惑有所幫助!接下來,請跟著小編一起來學(xué)習(xí)吧!

本篇文章分享一個簡單的socket示例,用php。實現(xiàn)一個接收輸入字符串,處理并返回這個字符串到客戶端的TCP服務(wù)。

產(chǎn)生一個 socket 服務(wù)端

<?php
/*文件名:socket_server.php*/
// 設(shè)置一些基本的變量
$host="127.0.0.1";//Socket運(yùn)行的服務(wù)器的IP地址
$port=1234;//Socket運(yùn)行的服務(wù)器的端口,端口取值為1到65535之間的數(shù)字,前提是這個端口未被使用
// 設(shè)置超時時間,這里設(shè)置為永不超時,確保PHP在等待客戶端連接時不會超時。
set_time_limit(0);
// 創(chuàng)建一個Socket,返回一個Socket句柄
$socket=socket_create(AF_INET,SOCK_STREAM,0) or die("Could not create socket\n");
//綁定Socket到指定的地址和端口
$result=socket_bind($socket,$host,$port) or die("Could not bind to socket\n");
// 開始監(jiān)聽外部連接
$result=socket_listen($socket,3) or die("Could not set up socket listener\n");
/******到這里,服務(wù)器除了等待來自客戶端的連接請求外基本上什么也不做******/
// 另一個Socket來處理服務(wù)端與客戶端的通信
$spawn=socket_accept($socket) or die("Could not accept incoming connection\n");
// 讀取客戶端的輸入,當(dāng)一個連接被建立后,服務(wù)器就會等待客戶端發(fā)送一些輸入信息,這些信息可以由socket_read()函數(shù)來獲得,并把它賦值給PHP的$input變量
$input=socket_read($spawn,1024) or die("Could not read input\n");
//socker_read的第二個參數(shù)用以指定讀入的字節(jié)數(shù),你可以通過它來限制從客戶端獲取數(shù)據(jù)的大小
// 下面這不就不解釋了,不知道的自己面壁去
$input=trim($input);
//處理客戶端輸入并返回結(jié)果,當(dāng)客戶端發(fā)來數(shù)據(jù)信息后,信息輸出就要靠socket_write()函數(shù)來完成
$output=strrev($input) ."\n";//反轉(zhuǎn)字符串,這里僅僅是為了更好的區(qū)分兩條信息
socket_write($spawn,$output,strlen($output)) or die("Could not write output\n");
// 關(guān)閉sockets
socket_close($spawn);
socket_close($socket);

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

復(fù)制代碼 代碼如下:


set_time_limit(0);


在你的命令提示符中對這個腳本進(jìn)行簡單測試:

復(fù)制代碼 代碼如下:


Php.exe socket_server.php


如果你沒有在系統(tǒng)的環(huán)境變量中設(shè)置php解釋器的路徑,那么你將需要給php.exe指定詳細(xì)的路徑。當(dāng)你運(yùn)行這個服務(wù)器端的時候,你能夠通過遠(yuǎn)程登陸(telnet)的方式連接到端口1337來測試這個服務(wù)器。

上面的服務(wù)器端有三個問題:

1. 它不能接受多個連接。

2. 它只完成唯一的一個命令。

3. 你不能通過Web瀏覽器連接這個服務(wù)器。

這個第一個問題比較容易解決,你可以使用一個應(yīng)用程序去每次都連接到服務(wù)器。但是后面的問題是你需要使用一個Web頁面去連接這個服務(wù)器,這個比較困難。你可以讓你的服務(wù)器接受連接,然后些數(shù)據(jù)到客戶端(如果它一定要寫的話),關(guān)閉連接并且等待下一個連接。

在上一個代碼的基礎(chǔ)上再改進(jìn),產(chǎn)生下面的代碼來做你的新服務(wù)器端:

<?php
$commonProtocol = getprotobyname("tcp");
$socket = socket_create(AF_INET, SOCK_STREAM, $commonProtocol);
socket_bind($socket, 'localhost', 1337); //socket_bind() 把socket綁定在一個IP地址和端口上
socket_listen($socket);
$buffer = "NO DATA";
while(true) {
 // Accept any connections coming in on this socket
 $connection = socket_accept($socket);//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"); //socket_write() 寫數(shù)據(jù)到socket緩存
 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)){//socket_read() 讀取指定長度的數(shù)據(jù)
 $buffer = $data;
 socket_write($connection, "Information Received\r\n");
 printf("Buffer: " . $buffer . "\r\n");
 }
 socket_close($connection); //socket_close() 關(guān)閉一個socket資源
 printf("Closed the socket\r\n\r\n");
}


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

產(chǎn)生一個 socket 客戶端

處理第二個問題是很容易的。你需要產(chǎn)生一個php頁連接一個socket,發(fā)送一些數(shù)據(jù)進(jìn)它的緩存并處理它。然后你有個處理后的數(shù)據(jù)在還頓,你能夠發(fā)送你的數(shù)據(jù)到服務(wù)器。在另外一臺客戶端連接,它將處理那些數(shù)據(jù)。

下面的例子示范了使用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 phpernote.com
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>");

這個例子的代碼演示了客戶端連接到服務(wù)器??蛻舳俗x取數(shù)據(jù)。如果這是第一時間到達(dá)這個循環(huán)的首次連接,這個服務(wù)器將發(fā)送“NO DATA”返回給客戶端。如果情況發(fā)生了,這個客戶端在連接之上??蛻舳税l(fā)送它的數(shù)據(jù)到服務(wù)器,數(shù)據(jù)發(fā)送給服務(wù)器,客戶端等待響應(yīng)。一旦接受到響應(yīng),那么它將把響應(yīng)寫到屏幕上。

到此,關(guān)于“php怎么實現(xiàn)簡單的socket服務(wù)器客戶端”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識,請繼續(xù)關(guān)注億速云網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI