千家信息网

php socket编程中客户端异常关闭导致服务端中断的问题怎么解决

发表于:2024-09-24 作者:千家信息网编辑
千家信息网最后更新 2024年09月24日,这篇文章主要讲解了"php socket编程中客户端异常关闭导致服务端中断的问题怎么解决",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"php sock
千家信息网最后更新 2024年09月24日php socket编程中客户端异常关闭导致服务端中断的问题怎么解决

这篇文章主要讲解了"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

 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

 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)

 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编程中客户端异常关闭导致服务端中断的问题怎么解决这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是,小编将为大家推送更多相关知识点的文章,欢迎关注!

0