首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网站开发 > PHP >

php socket编程 读完成后写堵塞

2013-10-27 
php socket编程 读完成后写阻塞server端代码 如下:?phpset_time_limit(0) $host 127.0.0.1$port

php socket编程 读完成后写阻塞
server端代码 如下:


<?php
set_time_limit(0);
 
$host = "127.0.0.1";
$port = 12345;
 
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP) or die("Could not createsocket\n"); // 创建一个Socket
 
$result = socket_bind($socket, $host, $port) or die("Could not bind tosocket\n"); //绑定Socket到端口
 
$result = socket_listen($socket) or die("Could not set up socket listener\n"); // 开始监听连接
 
$spawn = socket_accept($socket) or die("Could not accept incoming connection\n"); // 处理通信

//若换成循环接收数据,客户端将一直处理等待接收状态
$input = socket_read($spawn, 1024) or die("Could not read data\n");
/* 
while (( $data = socket_read($spawn, 1024)) != false) 
$input .= $data;
*/ 

echo 'input:', strlen($input), "\n";
 
$output = date("Y-m-d H:i:s"). "\n"; //处理客户端输入并返回结果
 
echo "output:", $output, "\n";
 
//数据传送 向客户端写入返回结果
socket_write($spawn, $output, strlen($output)) or die("Could not write output\n");
 
// 关闭sockets
socket_close($spawn);
socket_close($socket);


client端, 代码如下:

<?php

set_time_limit(0);
 
$host = "127.0.0.1";
$port = 12345;
 
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)or die("Could not createsocket\n"); // 创建一个Socket
 
$connection = socket_connect($socket, $host, $port) or die("Could not connet server\n");    //  连接
 
socket_write($socket, "time") or die("Write failed\n"); // 数据传送 向服务器发送消息

echo 'wait for data';

while (($buffer = socket_read($socket, 1024))!=false) {
    echo("Data sent was: time\nResponse was:" . $buffer . "\n");
}
 
socket_close($socket);

如果将server端对client read操作换成循环内部读取,则client会一直处于 wait data状态。
有办法让server端循环读的情况下,读完后给client写数据吗



socket tcp php server
[解决办法]
你这个循环没有错,但是一次数据发送完成就关闭socket连接了,没有循环的必要吧。
[解决办法]
while (true) {
    $msg = socket_accept ($socket);               // 接受一个SOCKET
    if (!$msg) {
        echo "socket_accept() failed:".socket_strerror ($msg)."\n";
        break;
    }
    while (true) {
        $command = strtoupper (trim (socket_read ($msg, 1024))); //等待客户端数据
        if (!$command) break;
        //相关处理,比如直接回显
        socket_write ($msg, $command, strlen ($command));
    }
    socket_close ($msg);
    if ($command == "QUIT") //如果收到的是通讯结束
        break;
}
socket_close ($socket);                   // 关闭SOCKET

[解决办法]
引用:
Quote: 引用:


<?php
set_time_limit(0);
 
$host = "127.0.0.1";
$port = 12345;
 
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP) or die("Could not createsocket\n"); // 创建一个Socket
 
$result = socket_bind($socket, $host, $port) or die("Could not bind tosocket\n"); //绑定Socket到端口
 
$result = socket_listen($socket) or die("Could not set up socket listener\n"); // 开始监听连接
 
$spawn = socket_accept($socket) or die("Could not accept incoming connection\n"); // 处理通信

//若换成循环接收数据,客户端将一直处理等待接收状态
$input = socket_read($spawn, 1024) or die("Could not read data\n");


 
while (( $input = socket_read($spawn, 1024)) != false) 
{



echo 'input:', strlen($input), "\n";
 
$output = date("Y-m-d H:i:s"). "\n"; //处理客户端输入并返回结果
 
echo "output:", $output, "\n";
 
//数据传送 向客户端写入返回结果
socket_write($spawn, $output, strlen($output)) or die("Could not write output\n");
}
// 关闭sockets
socket_close($spawn);
socket_close($socket);


读循环里面确实不应该用PHP_NORMAL_READ这个选项
去掉PHP_NORMAL_READ这个选项也不能解决问题,有解决方法吗

我都是用流函数实现的。
<?php

/*
 * 不使用apache,cli模式
 * 命令接收端
 * 单用户,即单连接
 */

/**
 * 命令接收端Messenger
 * 单线程
 */
class SocketServer {

    protected $ip;
    protected $port;
    protected $webSocket;
    protected $users;
    protected $userIndex = 0;
    protected $message;

    public function __construct($ip = "127.0.0.1", $port = 12345) {
        $this->ip = $ip;
        $this->port = $port;
        //
        self::init();
        //
        $this->createServer();
        $this->log('listenning user...');
        $this->listenningUser();
    }

    protected function createServer() {
        $errno;
        $errstr;
        $this->webSocket = stream_socket_server("tcp://" . $this->ip . ':' . $this->port, $errno, $errstr);
        if (!$this->webSocket) {
            self::log("$errstr ($errno)");
            exit();
        }
        $this->log('server ok .');
    }

    protected function listenningUser() {
        while (true) {
            $this->userIndex++;
            $user = $this->users[$this->userIndex] = stream_socket_accept($this->webSocket, 9999999999);
            //
            if (is_resource($this->users[$this->userIndex - 1])) {
                $u = $this->users[$this->userIndex - 1];
                $u->close();
                $u = NULL;
                unset($this->users[$this->userIndex - 1]);
            }
            //
            $this->log('连入新用户');
            $this->listenningMessage();
        }
    }

    protected function listenningMessage() {
        while (is_resource($this->users[$this->userIndex])) {
            $this->message = stream_socket_recvfrom($this->users[$this->userIndex], 10270000);
            if (!$this->message) {
                $this->closeUser();
                break;
            }
            $this->messageOperate();
        }
    }

    function messageOperate() {
        $this->log("收到消息:");
        $this->log($this->message);
        //mb_strstr($haystack, $needle, $before_needle, $encoding)


        $this->sendMessage('done');
    }

    function sendMessage($msg) {
        if($msg===''){
            return -1;
        }
        return stream_socket_sendto($this->users[$this->userIndex], $msg);
    }

    public function closeUser() {
        if (!is_resource($this->users[$this->userIndex]))
            return FALSE;
        @stream_socket_shutdown($this->users[$this->userIndex], STREAM_SHUT_RDWR);
        @fclose($this->users[$this->userIndex]);
        $this->log("用户连接断开.");
        return TRUE;
    }

    public function shutdown() {
        stream_socket_shutdown($this->webSocket, STREAM_SHUT_RDWR);
        fclose($this->webSocket);
    }

    protected static function init() {
        error_reporting(E_ALL ^ E_NOTICE);
        set_time_limit(0);
        ob_implicit_flush();
        date_default_timezone_set('Asia/Shanghai');
        ignore_user_abort(TRUE);
        mb_internal_encoding('gbk');
    }

    protected static function log($message) {
        echo "\r\n" . $message . "\r\n";
    }

}




$server = new SocketServer();




<?php

/*
 * 不使用apache,cli模式
 * 客户端
 */

class SocketClient {

    protected $client;
    protected $message;

    public function __construct($domain,$port) {
        $this->init();
        $this->client = stream_socket_client("tcp://$domain:$port", $errno, $errstr, 300000);
        if (!$this->client) {
            $this->log("$errstr ($errno)");
            return FALSE;
        }
        $this->log('client ok');
    }

    protected static function init() {
        error_reporting(E_ALL ^ E_NOTICE);
        //error_reporting(0);
        set_time_limit(0);
        ob_implicit_flush();
        date_default_timezone_set('Asia/Shanghai');
        ignore_user_abort(TRUE);
        mb_internal_encoding('gbk');
    }

    public function sendMessage($msg) {
        if ($msg === '') {
            return -1;
        }
        try {
            stream_socket_sendto($this->client, $msg);
        } catch (Exception $exc) {
            //$this->log($exc->getTraceAsString());
        }
    }

    public function getMessage() {
        $this->message = stream_socket_recvfrom($this->client, 10270000);
        //$this->log("收到消息:");
        //$this->log($this->message);
        fwrite(STDOUT, $this->message . "\r\n");
    }

    public function shutdown() {
        stream_socket_shutdown($this->client, STREAM_SHUT_RDWR);
        fclose($this->client);
    }

    public static function log($message) {


        echo "\r\n" . $message . "\r\n";
    }

}

//

$client = new SocketClient('127.0.0.1',12345);
while (true) {

    $msg = fread(STDIN, 9999999);
    if (!trim($msg)) {
        continue;
    }
    $client->sendMessage($msg);
    $client->getMessage();
}

热点排行