PHP8引入了替换旧套接字资源的套接字类。现在,所有套接字函数都与该类的实例一起工作。
EventListener构造函数(https://www.php.net/manual/en/class.eventlistener.php)的第二个参数是回调函数。当新连接事件出现时,将调用它。有此回调函数的签名:https://www.php.net/manual/en/eventlistener.setcallback.php。它接收文件描述符作为第二个参数。文件描述符是数值,但我需要套接字类的实例,因为接下来我将把它传递给EventBufferEvent的构造函数。
请告知如何获取该文件描述符的套接字实例?
无效的解决方案:
我试图找到绑定到文件描述符的地址和端口,然后创建新的套接字并将其绑定到这个地址和端口。但这会创建具有新文件描述符的新套接字,而与事件侦听器回调中接收的连接无关。
在将基于事件的套接字服务器迁移到php8时,我被困在为我的问题找到任何有用的文档或代码示例上。
发布于 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文档。它通过套接字实例接收资源和结果。这是我们所需要的,但是文件描述符不是一个资源。但是,有方法可以打开文件描述符并获取其资源。以下是解决办法:
$filename = sprintf("php://fd/%d", $clientResourceFd);
$clientResource = fopen($filename, 'rb');
$clientSocket = socket_import_stream($clientResource);好消息是它在linux中工作。有什么建议吗,如何使它在窗口中工作?
发布于 2022-02-08 14:27:51
Use还可以使用无文档的EventUtil::createSocket函数:
$socket = EventUtil::createSocket($fd);
socket_set_nonblock($socket);
$socketFd = EventUtil::getSocketFd($socket);只需确保将对套接字的引用保存在某个地方,如果您将$fd与其他类(如EventBufferEvent )一起使用。否则,$socket变量可能与基础文件描述符一起关闭。
发布于 2022-07-18 06:11:17
php8可以使用这个(从pecl事件)
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);
}https://stackoverflow.com/questions/70888098
复制相似问题