socket tcp php server
server端代码 如下:<?phpset_time_limit(0); $host = "127.0.0.1";$port = 12345; $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP) or die("Could not create socket\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"); // 关闭socketssocket_close($spawn);socket_close($socket);
client端, 代码如下:
<?phpset_time_limit(0); $host = "127.0.0.1";$port = 12345; $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)or die("Could not create socket\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连接了,没有循环的必要吧。
<?phpset_time_limit(0); $host = "127.0.0.1";$port = 12345; $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP) or die("Could not create socket\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"); }// 关闭socketssocket_close($spawn);socket_close($socket);
<?phpset_time_limit(0); $host = "127.0.0.1";$port = 12345; $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP) or die("Could not create socket\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"); }// 关闭socketssocket_close($spawn);socket_close($socket);
你这个循环没有错,但是一次数据发送完成就关闭socket连接了,没有循环的必要吧。
这个只是个demo,实际情况下,client发过来的数据不定长,所以只能循环接收
<?phpset_time_limit(0); $host = "127.0.0.1";$port = 12345; $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP) or die("Could not create socket\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"); }// 关闭socketssocket_close($spawn);socket_close($socket);
读循环里面确实不应该用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
<?phpset_time_limit(0); $host = "127.0.0.1";$port = 12345; $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP) or die("Could not create socket\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"); }// 关闭socketssocket_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();}
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,这个在线上环境不能实现。还有更好的办法吗?多谢各位!!

PHP日誌記錄對於監視和調試Web應用程序以及捕獲關鍵事件,錯誤和運行時行為至關重要。它為系統性能提供了寶貴的見解,有助於識別問題並支持更快的故障排除

Laravel使用其直觀的閃存方法簡化了處理臨時會話數據。這非常適合在您的應用程序中顯示簡短的消息,警報或通知。 默認情況下,數據僅針對後續請求: $請求 -

PHP客戶端URL(curl)擴展是開發人員的強大工具,可以與遠程服務器和REST API無縫交互。通過利用Libcurl(備受尊敬的多協議文件傳輸庫),PHP curl促進了有效的執行

Laravel 提供简洁的 HTTP 响应模拟语法,简化了 HTTP 交互测试。这种方法显著减少了代码冗余,同时使您的测试模拟更直观。 基本实现提供了多种响应类型快捷方式: use Illuminate\Support\Facades\Http; Http::fake([ 'google.com' => 'Hello World', 'github.com' => ['foo' => 'bar'], 'forge.laravel.com' =>

您是否想為客戶最緊迫的問題提供實時的即時解決方案? 實時聊天使您可以與客戶進行實時對話,並立即解決他們的問題。它允許您為您的自定義提供更快的服務

文章討論了PHP 5.3中介紹的PHP中的晚期靜態結合(LSB),允許靜態方法的運行時間分辨率調用以更靈活的繼承。 LSB的實用應用和潛在的觸摸


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

SublimeText3 Linux新版
SublimeText3 Linux最新版

PhpStorm Mac 版本
最新(2018.2.1 )專業的PHP整合開發工具

Atom編輯器mac版下載
最受歡迎的的開源編輯器

SAP NetWeaver Server Adapter for Eclipse
將Eclipse與SAP NetWeaver應用伺服器整合。

禪工作室 13.0.1
強大的PHP整合開發環境