将套接字资源转换为流套接字。

时间:2021-04-25 23:56:53

PHP has two different APIs for interacting with sockets. There is the low level socket API which basically wraps the C socket API. And there is the high level stream sockets API, which implements the PHP stream interface.

PHP有两个不同的api用于与套接字交互。有一个底层套接字API,它基本上封装了C套接字API。还有高级流套接字API,它实现PHP流接口。

Unfortunately, the stream socket API does not support setting low level socket options. However, this is something that I have to do. Likewise, the socket API does not support using standard function calls like fread, fwrite and fclose, making it incompatible with the rest of my code.

不幸的是,流套接字API不支持设置低级别套接字选项。然而,这是我必须要做的。同样,套接字API不支持使用像fread、fwrite和fclose这样的标准函数调用,这使得它与我的其余代码不兼容。

PHP 5.4 introduced the socket_import_stream function. This allows you to take a stream socket and get the underlying socket resource. My plan was to use this to create the stream socket, get the socket, set some options on it, and then continue using the original stream socket.

PHP 5.4引入了socket_import_stream函数。这允许您获取流套接字并获取底层套接字资源。我的计划是使用它来创建流套接字,获取套接字,在它上设置一些选项,然后继续使用原始的流套接字。

The reason this did not work for me is that I need to set the options before binding. The only way to bind a stream socket is to use stream_socket_server, which already performs the bind. That's why I could not use it.

这对我不起作用的原因是我需要在绑定之前设置选项。绑定流套接字的唯一方法是使用stream_socket_server,它已经执行了绑定。这就是为什么我不能使用它。

I am now looking for the inverse of socket_import_stream, so that I can convert my socket resource into a stream socket. I have not been able to find such a function, but I'm hoping that some very smart people can help me. Or submit a patch to the PHP source that does it. Or give me hints on writing such a patch.

我现在正在查找socket_import_stream的逆,这样我就可以将我的socket资源转换为流套接字。我还没有找到这样的功能,但我希望一些非常聪明的人能帮助我。或者向PHP源代码提交补丁。或者给我写这样一个补丁的提示。

EDIT: I have some code that acts on a PHP stream to parse DNS packets from it. I want to re-use that code with a multicast-enabled socket. I cannot enable multicast on a stream socket, and I cannot use stream functions on a raw socket.

编辑:我有一些代码可以作用于PHP流来解析DNS包。我想要使用支持多播的套接字来重用该代码。我不能在流套接字上启用多播,也不能在原始套接字上使用流函数。

EDIT2: I want to use this stream with stream_select, so custom stream wrappers are not an option, unfortunately.

EDIT2:我想用stream_select来使用这个流,不幸的是,自定义流包装器不是一个选项。

2 个解决方案

#1


6  

You can use the stream_wrapper_register function in combination with a class which implements the streamWrapper template to create a multicast socket stream. This will allow you to leverage all of the built in stream functions, though it is not as convenient as socket_export_stream.

您可以结合使用stream_wrapper_register函数和实现streamWrapper模板以创建多播套接字流的类。这将允许您利用所有构建的流函数,尽管它没有socket_export_stream那么方便。

#2


5  

The reason this did not work for me is that I need to set the options before binding. The only way to bind a stream socket is to use stream_socket_server, which already performs the bind. That's why I could not use it.

这对我不起作用的原因是我需要在绑定之前设置选项。绑定流套接字的唯一方法是使用stream_socket_server,它已经执行了绑定。这就是为什么我不能使用它。

The 4th parameter of stream_socket_server() is $flags, which defaults to STREAM_SERVER_BIND | STREAM_SERVER_LISTEN, so do not ommit it, give 0 (or another flags).

stream_socket_server()的第四个参数是$flags,它默认为STREAM_SERVER_BIND | STREAM_SERVER_LISTEN,所以不要忽略它,给出0(或其他标志)。

After all setting is done, you can still manually bind (& listen) that socket using socket_bind() & socket_listen().

完成所有设置之后,仍然可以使用socket_bind()和socket_listen()手动绑定(& listen)那个套接字。

I didn't tried, just an idea.

我没有尝试,只是一个想法。

#1


6  

You can use the stream_wrapper_register function in combination with a class which implements the streamWrapper template to create a multicast socket stream. This will allow you to leverage all of the built in stream functions, though it is not as convenient as socket_export_stream.

您可以结合使用stream_wrapper_register函数和实现streamWrapper模板以创建多播套接字流的类。这将允许您利用所有构建的流函数,尽管它没有socket_export_stream那么方便。

#2


5  

The reason this did not work for me is that I need to set the options before binding. The only way to bind a stream socket is to use stream_socket_server, which already performs the bind. That's why I could not use it.

这对我不起作用的原因是我需要在绑定之前设置选项。绑定流套接字的唯一方法是使用stream_socket_server,它已经执行了绑定。这就是为什么我不能使用它。

The 4th parameter of stream_socket_server() is $flags, which defaults to STREAM_SERVER_BIND | STREAM_SERVER_LISTEN, so do not ommit it, give 0 (or another flags).

stream_socket_server()的第四个参数是$flags,它默认为STREAM_SERVER_BIND | STREAM_SERVER_LISTEN,所以不要忽略它,给出0(或其他标志)。

After all setting is done, you can still manually bind (& listen) that socket using socket_bind() & socket_listen().

完成所有设置之后,仍然可以使用socket_bind()和socket_listen()手动绑定(& listen)那个套接字。

I didn't tried, just an idea.

我没有尝试,只是一个想法。