揭開socket的神秘面紗

php中socket的應(yīng)用

php中socket函數(shù)

函數(shù)名 描述

socket_accept() 接受一個(gè)Socket連接

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

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

socket_close() 關(guān)閉一個(gè)socket資源

socket_connect() 開始一個(gè)socket連接

socket_create_listen() 在指定端口打開一個(gè)socket監(jiān)聽

socket_create_pair() 產(chǎn)生一對沒有差別的socket到一個(gè)數(shù)組里

socket_create() 產(chǎn)生一個(gè)socket,相當(dāng)于產(chǎn)生一個(gè)socket的數(shù)據(jù)結(jié)構(gòu)

socket_get_option() 獲取socket選項(xiàng)

socket_getpeername() 獲取遠(yuǎn)程類似主機(jī)的ip地址

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

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

socket_iovec_alloc() 這個(gè)函數(shù)創(chuàng)建一個(gè)能夠發(fā)送接收讀寫的iovec數(shù)據(jù)結(jié)構(gòu)

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

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

socket_iovec_free() 釋放一個(gè)iovec資源

socket_iovec_set() 設(shè)置iovec的數(shù)據(jù)新值

socket_last_error() 獲取當(dāng)前socket的最后錯(cuò)誤代碼

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

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

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

socket_recv() 從socket里結(jié)束數(shù)據(jù)到緩存

socket_recvfrom() 接受數(shù)據(jù)從指定的socket,如果沒有指定則默認(rèn)當(dāng)前socket

socket_recvmsg() 從iovec里接受消息

socket_select() 多路選擇

socket_send() 這個(gè)函數(shù)發(fā)送數(shù)據(jù)到已連接的socket

socket_sendmsg() 發(fā)送消息到socket

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

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

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

socket_set_option() 設(shè)置socket選項(xiàng)

socket_shutdown() 這個(gè)函數(shù)允許你關(guān)閉讀、寫、或指定的socket

socket_strerror() 返回指定錯(cuò)誤號的周詳錯(cuò)誤

socket_write() 寫數(shù)據(jù)到socket緩存

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

使用PHP socket擴(kuò)展

開啟PHP中socket擴(kuò)展

image.png

如上圖所示,開啟擴(kuò)展后可以在php探針中顯示。

下面來用phg做一個(gè)socket通信實(shí)例:

服務(wù)器端:

<?php
/**
 * Created by PhpStorm.
 * User: Mr.Li
 * Date: 2017/12/16
 * Time: 17:18
 */
//創(chuàng)建socket
set_time_limit(0);   //確保在連接客戶端時(shí)不會(huì)超時(shí)
//設(shè)置IP和端口號
$address = "127.0.0.1";
$port = 8888;
$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP) or die("socket_create() 失敗的原因是:" . socket_strerror(socket_last_error()) . "/n");
//阻塞模式
socket_set_block($sock) or die("socket_set_block() 失敗的原因是:" . socket_strerror(socket_last_error()) . "/n");
//綁定到socket端口
$result = socket_bind($sock, $address, $port) or die("socket_bind() 失敗的原因是:" . socket_strerror(socket_last_error()) . "/n");
//開始監(jiān)聽
$result = socket_listen($sock, 4) or die("socket_listen() 失敗的原因是:" . socket_strerror(socket_last_error()) . "/n");
do { // never stop the daemon
    //它接收連接請求并調(diào)用一個(gè)子連接Socket來處理客戶端和服務(wù)器間的信息
    $msgsock = socket_accept($sock) or  die("socket_accept() failed: reason: " .               
    socket_strerror(socket_last_error()) . "/n");
    //讀取客戶端數(shù)據(jù)
    echo "Read client data \n";
    //socket_read函數(shù)會(huì)一直讀取客戶端數(shù)據(jù),直到遇見\n,\t或者\(yùn)0字符.PHP腳本把這寫字符看做是輸入的結(jié)束符.
    $buf = socket_read($msgsock, 8192);
    echo "Received msg: $buf   \n";

    //數(shù)據(jù)傳送 向客戶端寫入返回結(jié)果
    $msg = "測試成功 \n";
    socket_write($msgsock, $msg, strlen($msg)) or die("socket_write() failed: reason: " . socket_strerror(socket_last_error()) ."/n");
    //一旦輸出被返回到客戶端,父/子socket都應(yīng)通過socket_close($msgsock)函數(shù)來終止
    socket_close($msgsock);
} while (true);
socket_close($sock);

客戶端:

<?php
/**
 * Created by PhpStorm.
 * User: Mr.Li
 * Date: 2017/12/16
 * Time: 17:21
 */
error_reporting(E_ALL);
set_time_limit(0);
$ip = '127.0.0.1';
$port =8888;

// 1. 創(chuàng)建
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);

if( $socket == FALSE ) {
    echo 'create fail: ' . socket_strerror(socket_last_error());
} else {
    echo 'OK';
}
// 2. 鏈接
echo 'we will try to connect ' . $ip .':' . $port . '\r\n----';
$result = socket_connect($socket, $ip, $port);
if ( $result == FALSE) {
}

$in = 'HO ';
$in .= 'first blood--------';
$out = '';

// 3. 向服務(wù)端寫入
if( !socket_write($socket, $in, strlen($in)) ) {
    echo 'write fail: ' . socket_strerror(socket_last_error());
} else {
    echo '-----send to server succefully! \r\n----';
    echo 'the content is ' . $in;
}

// 3. 從服務(wù)端讀取
while ( $out = socket_read($socket, 102400)){
    echo '-----receive from server succefully!\r\n------';
    echo 'the contents is ' . $out;
}

// 4. 關(guān)閉
echo '----close socket ...';
socket_close($socket);
echo 'closed ok.';

然后使用cli方式啟動(dòng)server:


image.png

image.png

可以看到8888端口已經(jīng)被監(jiān)聽,說明socket服務(wù)端程序開始運(yùn)行。下面再啟動(dòng)客戶端:


image.png

從上圖可以看到客戶端向服務(wù)器端發(fā)送成功
再看服務(wù)器端接收
image.png

服務(wù)端也可以收到消息。

以上就是整個(gè)的socket客戶端和服務(wù)器端的通信。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 對TCP/IP、UDP、Socket編程這些詞你不會(huì)很陌生吧?隨著網(wǎng)絡(luò)技術(shù)的發(fā)展,這些詞充斥著我們的耳朵。那么我想...
    yuantao123434閱讀 5,522評論 1 97
  • php usleep() 函數(shù)延遲代碼執(zhí)行若干微秒。 unpack() 函數(shù)從二進(jìn)制字符串對數(shù)據(jù)進(jìn)行解包。 uni...
    思夢PHP閱讀 2,133評論 1 24
  • PHP常用函數(shù)大全 usleep() 函數(shù)延遲代碼執(zhí)行若干微秒。 unpack() 函數(shù)從二進(jìn)制字符串對數(shù)據(jù)進(jìn)行解...
    上街買菜丶迷倒老太閱讀 1,487評論 0 20
  • 第一章 Nginx簡介 Nginx是什么 沒有聽過Nginx?那么一定聽過它的“同行”Apache吧!Ngi...
    JokerW閱讀 33,011評論 24 1,002
  • 如果有個(gè)有獎(jiǎng)問答,問到大學(xué)四年學(xué)到了什么,對我而言,就是真誠的贊美別人而不會(huì)覺得委屈自己,進(jìn)行果斷的抉擇并敢于承擔(dān)...
    小朋是個(gè)寶寶閱讀 197評論 0 0

友情鏈接更多精彩內(nèi)容