Home » Php » php – Converting a socket resource into a stream socket

php – Converting a socket resource into a stream socket

Posted by: admin April 23, 2020 Leave a comment

Questions:

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.

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.

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.

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.

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.

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.

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

How to&Answers:

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.

Answer:

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.

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).

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

I didn’t tried, just an idea.