php socket编程 读完成后写阻塞
程序员文章站
2022-05-24 15:08:31
...
socket tcp php server server端代码 如下:
client端, 代码如下:
如果将server端对client read操作换成循环内部读取,则client会一直处于 wait data状态。
有办法让server端循环读的情况下,读完后给client写数据吗回复讨论(解决方案)
你这个循环没有错,但是一次数据发送完成就关闭socket连接了,没有循环的必要吧。
你这个循环没有错,但是一次数据发送完成就关闭socket连接了,没有循环的必要吧。
这个只是个demo,实际情况下,client发过来的数据不定长,所以只能循环接收
读循环里面确实不应该用PHP_NORMAL_READ这个选项
去掉PHP_NORMAL_READ这个选项也不能解决问题,有解决方法吗
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
读循环里面确实不应该用PHP_NORMAL_READ这个选项
去掉PHP_NORMAL_READ这个选项也不能解决问题,有解决方法吗
我都是用流函数实现的。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();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();}
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
版主好
这里我需要读取完client放的数据分析后才能write回client端,你想让client那边发送quit命令结束socket,这个在线上环境不能实现。还有更好的办法吗?多谢各位!!