91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

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

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

php socket編程中客戶端異常關閉導致服務端中斷的問題怎么解決

發布時間:2021-09-03 19:16:29 來源:億速云 閱讀:223 作者:chen 欄目:大數據

這篇文章主要講解了“php socket編程中客戶端異常關閉導致服務端中斷的問題怎么解決”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“php socket編程中客戶端異常關閉導致服務端中斷的問題怎么解決”吧!


原因如下:
1.socket_recv支持多種flag,用于不同場景
2.socket_recv可以檢測socket關閉的情況(例如對端關閉了socket)
返回值:$return_value=socket_recv(...)
含義: >0 表示接收到的字節數;
===0, 發生了錯誤,socket closed;
===false,無數據,socket not closed。

socket_read不能判斷socket是否已經斷開。
測試流程:
啟動server端,再啟動client端:可以正常通信。
kill掉client端,結果server端只能讀取到空字符串。

測試代碼如下:

file: bug1_server.php

<?php
/**
 * file: bug1_server.php
 * socket server
 * 基于php socket函數族
 * IO模型:同步阻塞
 * 粘包處理:固定長度
 * 連接數:1個socket連接
 *
 * 測試目標:模擬client crash時,server無法判斷socket是否斷開
 * 測試結果:kill殺掉client進程后,server進程socket_last_error()返回為0,無法判斷socket是否關閉
 *
 * @author davidyanxw
 * @date 2018.04.27
 */

set_time_limit(0);

//創建服務端的socket套接流,net協議為IPv4,protocol協議為TCP
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);

// reuse address
socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1);

/*綁定接收的套接流主機和端口,與客戶端相對應*/
if (socket_bind($socket, '127.0.0.1', 8801) == false) {
    echo 'server bind fail:' . socket_strerror(socket_last_error());
}
//監聽套接流
if (socket_listen($socket, 4) == false) {
    echo 'server listen fail:' . socket_strerror(socket_last_error());
}

$accept_resource = socket_accept($socket);
if($accept_resource === false) {
    echo "accept connection failed".PHP_EOL;
    exit;
}
// 讀寫超時時間:0.8s
socket_set_option($accept_resource, SOL_SOCKET,     SO_RCVTIMEO, array("sec" => 0, "usec" => 800000));
socket_set_option($accept_resource, SOL_SOCKET,         SO_SNDTIMEO, array("sec" => 0, "usec" => 800000));

// stream固定長度
$len = 100;

//讓服務器不停獲取客戶端傳過來的信息
while (true) {
    $string_read = socket_read($accept_resource, $len);
    if($string_read === false) {
        echo "socket error:" . socket_last_error() . ",error msg:" . socket_strerror(socket_last_error()) . PHP_EOL;
        break;
    }
    elseif($string_read == '') {
        if(in_array(socket_last_error(), [SOCKET_EPIPE, SOCKET_ECONNRESET])) {
            echo "socket error:".socket_last_error().",error msg:".socket_strerror(socket_last_error()).PHP_EOL;
            break;
        }
        if(in_array(socket_last_error(), [SOCKET_EAGAIN])) {
        // EAGAIN, retry later
        usleep(500);
        continue;
    }
    echo "server receive empty:" . socket_last_error() . ",error msg:" . socket_strerror(socket_last_error()) . PHP_EOL;
}
else {
    $string = trim($string_read);
    echo 'server receive success,msg:['.$string.'],time:' . microtime(true) . PHP_EOL;
    }
} ;

// 先shutdown,后close
@socket_shutdown($accept_resource);
socket_close($accept_resource);

@socket_shutdown($socket);
socket_close($socket);

/**
 * 生成php隨機串
 * @param $length
 * @return string
 */
function randomkeys($length){
    $output='';
    for ($a = 0; $a<$length; $a++) {
        $output .= chr(mt_rand(33, 126));
    }
    return $output;
}
?>

file:bug1_client.php

<?php
/**
 * file:bug1_client.php
 * socket client
 * 基于php socket函數族
 * IO模型:同步阻塞
 * 粘包處理:固定長度
 * 連接數:1個socket連接
 *
 * @author davidyanxw
 * @date 2018.04.27
 */
set_time_limit(0);

//創建一個socket套接流
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);

//接收套接流的最大超時時間(800ms)
//發送套接流的最大超時時間(800ms)
socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, array("sec" => 0, "usec" => 800000));
socket_set_option($socket, SOL_SOCKET, SO_SNDTIMEO, array("sec" => 0, "usec" => 800000));

$len = 100;

//連接服務端的套接流,這一步就是使客戶端與服務器端的套接流建立聯系
if (socket_connect($socket, '127.0.0.1', 8801) == false) {
    echo 'connect fail massege:' . socket_strerror(socket_last_error());
} else {
    while(1){
        $ori_msg = 'Hello, server!'.randomkeys(8);
        $message_write = str_pad($ori_msg, $len);

        //向服務端寫入字符串信息
        $sent = @socket_write($socket, $message_write, $len);

        if ($sent === false) {
            if(in_array(socket_last_error(), [SOCKET_EPIPE, SOCKET_ECONNRESET])) {
                echo "socket error:".socket_last_error().",error msg:".socket_strerror(socket_last_error()).PHP_EOL;
                break;
            }
            echo "socket error:".socket_last_error().",error msg:".socket_strerror(socket_last_error()).PHP_EOL;
        }
        else{
            echo 'client write success,msg:['.$ori_msg.'],time:' . microtime(true).PHP_EOL;
        }
//        break;
    }
}
@socket_shutdown($socket);
socket_close($socket);

/**
 * 生成php隨機串
 * @param $length
 * @return string
 */
function randomkeys($length){
    $output='';
    for ($a = 0; $a<$length; $a++) {
        $output .= chr(mt_rand(33, 126));
    }
    return $output;
}
?>

正確的代碼是:(file: debug1_server.php)

<?php
/**
 * file: debug1_server.php
 * socket server
 * 基于php socket函數族
 * IO模型:同步阻塞
 * 粘包處理:固定長度
 * 連接數:1個socket連接
 *
 * 測試目標:模擬client crash時,server無法判斷socket是否斷開
 * 測試結果:kill殺掉client進程后,server進程socket_last_error()返回為0,無法判斷socket是否關閉
 *
 * @author davidyanxw
 * @date 2018.04.27
 */

set_time_limit(0);

//創建服務端的socket套接流,net協議為IPv4,protocol協議為TCP
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);

// reuse address
socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1);

/*綁定接收的套接流主機和端口,與客戶端相對應*/
if (socket_bind($socket, '127.0.0.1', 8801) == false) {
    echo 'server bind fail:' . socket_strerror(socket_last_error());
}
//監聽套接流
if (socket_listen($socket, 4) == false) {
    echo 'server listen fail:' . socket_strerror(socket_last_error());
}

$accept_resource = socket_accept($socket);
if($accept_resource === false) {
    echo "accept connection failed".PHP_EOL;
    exit;
}
// 讀寫超時時間:0.8s
socket_set_option($accept_resource, SOL_SOCKET, SO_RCVTIMEO, array("sec" => 0, "usec" => 800000));
socket_set_option($accept_resource, SOL_SOCKET, SO_SNDTIMEO, array("sec" => 0, "usec" => 800000));

// stream固定長度
$len = 100;

//讓服務器不停獲取客戶端傳過來的信息
while (true) {
    /* 使用socket_recv */
    $len_read = socket_recv($accept_resource, $string_read, $len, 0);
    
    if ($len_read === false) {
        // no data
        echo "no data".PHP_EOL;
        continue;
    }
    elseif($len_read === 0 ) {
        // socket closed
        echo "socket error:" . socket_last_error() . ",error msg:" . socket_strerror(socket_last_error()) . PHP_EOL;
        break;
    }
    else {
        $string = trim($string_read);
        echo 'server receive success,msg:['.$string.'],time:' . microtime(true) . PHP_EOL;
    }
} ;
// 先shutdown,后close
@socket_shutdown($accept_resource);
socket_close($accept_resource);

@socket_shutdown($socket);
socket_close($socket);

/**
 * 生成php隨機串
 * @param $length
 * @return string
 */
function randomkeys($length){
    $output='';
    for ($a = 0; $a<$length; $a++) {
        $output .= chr(mt_rand(33, 126));
    }
    return $output;
}
?>

感謝各位的閱讀,以上就是“php socket編程中客戶端異常關閉導致服務端中斷的問題怎么解決”的內容了,經過本文的學習后,相信大家對php socket編程中客戶端異常關閉導致服務端中斷的問題怎么解決這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

php
AI

丰城市| 华宁县| 揭西县| 富平县| 若羌县| 北票市| 四川省| 龙岩市| 通州市| 临桂县| 勃利县| 黎平县| 方山县| 九龙坡区| 专栏| 南昌市| 确山县| 平武县| 吴忠市| 积石山| 东至县| 石首市| 崇明县| 新化县| 吴川市| 淮安市| 抚顺市| 左权县| 布尔津县| 称多县| 任丘市| 宝清县| 疏附县| 乌鲁木齐县| 海门市| 禄丰县| 松溪县| 岳池县| 磐石市| 鱼台县| 迁西县|