首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PHP8 8/EventListener-从文件描述符获取套接字实例

PHP8 8/EventListener-从文件描述符获取套接字实例
EN

Stack Overflow用户
提问于 2022-01-28 02:16:21
回答 3查看 163关注 0票数 1

PHP8引入了替换旧套接字资源的套接字类。现在,所有套接字函数都与该类的实例一起工作。

EventListener构造函数(https://www.php.net/manual/en/class.eventlistener.php)的第二个参数是回调函数。当新连接事件出现时,将调用它。有此回调函数的签名:https://www.php.net/manual/en/eventlistener.setcallback.php。它接收文件描述符作为第二个参数。文件描述符是数值,但我需要套接字类的实例,因为接下来我将把它传递给EventBufferEvent的构造函数。

请告知如何获取该文件描述符的套接字实例?

无效的解决方案:

我试图找到绑定到文件描述符的地址和端口,然后创建新的套接字并将其绑定到这个地址和端口。但这会创建具有新文件描述符的新套接字,而与事件侦听器回调中接收的连接无关。

在将基于事件的套接字服务器迁移到php8时,我被困在为我的问题找到任何有用的文档或代码示例上。

EN

回答 3

Stack Overflow用户

发布于 2022-01-31 03:45:30

我们对Socket类知之甚少,PHP文档说它是“一个完全不透明的类”。因此,我必须研究sockets.so实现sockets.c的C源。我明白了,Socket对象是用php_socket结构描述的。

我还查看了头文件sockets.h。它包含函数签名PHP_SOCKETS_API int socket_import_file_descriptor(PHP_SOCKET socket, php_socket *retsock);。它接收套接字连接的文件描述符,并以指针指向结构的结果定义PHP套接字类的实例。让我们看看描述符()函数是如何在sockets.c中实现的。它可以满足我们的需要,但它没有导出到PHP作用域,因此我们无法调用它。

我在导出的函数中搜索socket_import_file_descriptor()的用法。它只从socket_import_stream()调用。让我们看看流(资源$stream):Socket=false的PHP文档。它通过套接字实例接收资源和结果。这是我们所需要的,但是文件描述符不是一个资源。但是,有方法可以打开文件描述符并获取其资源。以下是解决办法:

代码语言:javascript
复制
$filename = sprintf("php://fd/%d", $clientResourceFd);
$clientResource = fopen($filename, 'rb');
$clientSocket = socket_import_stream($clientResource);

好消息是它在linux中工作。有什么建议吗,如何使它在窗口中工作?

票数 0
EN

Stack Overflow用户

发布于 2022-02-08 14:27:51

Use还可以使用无文档的EventUtil::createSocket函数:

代码语言:javascript
复制
$socket = EventUtil::createSocket($fd);
socket_set_nonblock($socket);
$socketFd = EventUtil::getSocketFd($socket);

只需确保将对套接字的引用保存在某个地方,如果您将$fd与其他类(如EventBufferEvent )一起使用。否则,$socket变量可能与基础文件描述符一起关闭。

票数 0
EN

Stack Overflow用户

发布于 2022-07-18 06:11:17

php8可以使用这个(从pecl事件)

代码语言:javascript
复制
PHP_EVENT_METHOD(EventUtil, getSocketFd) {
        zval *pzfd = NULL;
        php_socket *php_sock;

        if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &pzfd) == FAILURE) {
                return;
        }
        php_sock = Z_SOCKET_P(pzfd);
        ENSURE_SOCKET_VALID(php_sock);

        if (Z_ISUNDEF(php_sock->zstream) && (!IS_INVALID_SOCKET(php_sock))) {
            RETURN_LONG(php_sock->bsd_socket);
        }

        RETVAL_LONG(pzfd ? php_event_zval_to_fd(pzfd) : -1);
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70888098

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档