读书人

php socket编程 读完成后写堵塞

发布时间: 2013-10-27 15:21:50 作者: rapoo

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();
}

读书人网 >PHP

热点推荐