PHP - fwrite() 不写入套接字

Posted

技术标签:

【中文标题】PHP - fwrite() 不写入套接字【英文标题】:PHP - fwrite() does not write to socket 【发布时间】:2021-05-14 14:58:15 【问题描述】:

我正在使用 php 开发一个面向对象的应用程序,该应用程序连接到远程服务器以读取和发送数据。为此,我使用fsockopen()fgets() 读取、fwrite() 写入和fclose()。 我将其简化为必要的代码:

<?php
namespace myApplication;

class client 
    protected $socket;
    public $connected = false;
    
    public function connect(string $host, int $port) : bool 
        if (($this->socket = fsockopen($host, $port, $errno, $errstr, 15)) == false) 
            return false; //or error handling
        
        $this->connected = true;
        return true;
    
    
    public function disconnect() 
        if ($this->connected) 
            @fclose($this->socket);
            $this->connected = false;
        
    
    
    
    public function read() : ?string 
        if ($this->connected === false) 
            /*
            throw error
            */
        
        
        if (($data = fgets($this->socket)) !== false) 
            return $data;
        
        else 
            /*
            error handling
            */
        
    
    
    public function write($write_data) : bool 
        if ($this->connected === false) 
            /*
            throw error
            */
        
        
        $write_data .= "\r\n"; //carriage return, newline
        if (fwrite($this->socket, $write_data, strlen($write_data)) != false) 
            return true;
        
        else 
            /*
            error handling
            */
            return false;
        
    

问题

首先,一切似乎都按预期进行。客户端连接到服务器,它成功检索到服务器发送的第一条问候语,并在调用fwrite() 时返回它成功写入所有字节。 (PHP 文档说函数的返回值是写入的字节数。)所以这一切似乎工作得很好。

但是服务器从不从客户端获取数据。我用我为调试目的编写的一个简单的 PHP 套接字服务器测试了客户端,但它也没有从客户端检索任何数据。

我不知道为什么会这样。连接已成功建立,如前所述,客户端可以从服务器检索数据。但是不知什么原因,fwrite() 没有成功发送数据。

没有错误或警告消息。日志级别E_ALL

版本和信息:

操作系统: Debian 10 Buster,最新版本的所有软件包。 php --version 输出: PHP 7.3.19-1~deb10u1

欲了解更多信息,请在此处提问,我会积极回答问题。

【问题讨论】:

不应该$write_data .= '\r\n';$write_data .= "\r\n"; 吗?即用双引号... 是的,你是对的!我在为这个问题写 sn-p 时犯了错误,我的错。我已经编辑了问题并修复了它。 【参考方案1】:

似乎在这种情况下fwrite 只写入缓冲区而不是直接发送数据。 可以用fflush强制发送。

【讨论】:

谢谢,到目前为止一切正常!但是为什么在这种情况下必须使用fflush?此外,应用程序的行为仍然很奇怪。数据仅在建立连接后大约 60 秒后发送,尽管我在发送和读取一行后调用类的 ::disconnect() 函数(在这种情况下,服务器在客户端发送数据后只发送一行)脚本仅在数据发送后约 40-60 秒后完成。有什么理由会这样吗?服务器还报告两条传入的数据行。 我无法在 PHP 文档中找到有关缓冲的更多信息。延迟对我来说很奇怪,我现在什至无法做出合理的猜测。

以上是关于PHP - fwrite() 不写入套接字的主要内容,如果未能解决你的问题,请参考以下文章

并发使用持久性 PHP 套接字

GCP Cloud 运行容器服务:[pool www] 无法写入套接字 '/run/php-fpm/www.sock' 的 ACL

使用 SSL 的流式套接字

PHP fwrite() 用于将大字符串写入文件

PHP 从 Windows 机器上的套接字读取

PHP fwrite() 无法写入子目录