Re: Sockets
| From: | Jason Greene | Date: | Wed, 08 May 2002 15:11:35 +0000 |
| Subject: | Re: Sockets | ||
| References: | 1 2 3 4 | Groups: | php.dev |
| Request: | Send a blank email to php-dev+get-83817@lists.php.net to get a copy of this message | ||
FYI
My goal is to mark this extension stable by 4.3, which means no more
base API changes.
-Jason
On Tue, 2002-05-07 at 17:04, J Smith wrote:
>
> Now that I look at it, I'm noticing that the example is for the old sockets
> API. See the attachment for a newer version that works with PHP 4.2.1RC2.
>
> J
>
>
>
> I wrote two seconds ago:
>
> >
> > I posted a sort-of example for a blocking socket server using
> > socket_select(). It should get you on your way. Note that the example was
> > written two months ago, so there may need to be a few changes. (One of
> > which is the socket_select() call -- change the null arguments for the
> > exceptfds and writefds to $null or something, as socket_select() now wants
> > arrays, period, no nulls or constants.)
> >
> > Also note the lack of error checking. It is just an example, after all.
> >
> >
> > http://marc.theaimsgroup.com/?l=php-dev&m=101561785202033&w=2
> >
> > J
> >
> ----
>
> #!/usr/local/bin/php -q
> <?php
>
> set_time_limit(0);
>
>
> // defaults...
>
> define('MAXLINE', 1024); // how much to read from a socket at a time
> define('LISTENQ', 10); // listening queue
> define('PORT', 10000); // the default port to run on
> define('FD_SETSIZE', 5); // file descriptor set size (max number of concurrent
> clients)...
>
>
> // for kill the biatch...
>
> function killDaemon()
> {
> global $listenfd, $client;
>
> socket_close($listenfd);
> $msg = "Daemon going down!\n";
> for ($i = 0; $i < FD_SETSIZE; $i++)
> {
> if ($client[$i] != null)
> {
> socket_write($client[$i], $msg, strlen($msg));
> socket_close($client[$i]);
> }
> }
>
> print "Shutting down the daemon\n";
> exit;
> }
>
>
> // whenever a client disconnects...
>
> function closeClient($i)
> {
> global $client, $remote_host, $remote_port;
>
> print "closing client[$i] ({$remote_host[$i]}:{$remote_port[$i]})\n";
>
> socket_close($client[$i]);
> $client[$i] = null;
> unset($remote_host[$i]);
> unset($remote_port[$i]);
> }
>
>
> // set up the file descriptors and sockets...
>
> // $listenfd only listens for a connection, it doesn't handle anything
> // but initial connections, after which the $client array takes over...
>
> $listenfd = socket_create(AF_INET, SOCK_STREAM, 0);
> if ($listenfd)
> print "Listening on port " . PORT . "\n";
> else
> die("AIEE -- socket died!\n");
>
> socket_setopt($listenfd, SOL_SOCKET, SO_REUSEADDR, 1);
> if (!socket_bind($listenfd, "0.0.0.0", PORT))
> {
> socket_close($listenfd);
> die("AIEE -- Couldn't bind!\n");
> }
> socket_listen($listenfd, LISTENQ);
>
>
> // set up our clients. After listenfd receives a connection,
> // the connection is handed off to a $client[]. $maxi is the
> // set to the highest client being used, which is somewhat
> // unnecessary, but it saves us from checking each and every client
> // if only, say, the first two are being used.
>
> $maxi = -1;
> for ($i = 0; $i < FD_SETSIZE; $i++)
> $client[$i] = null;
>
>
> // the main loop.
>
> while(1)
> {
> $rfds[0] = $listenfd;
>
> for ($i = 0; $i < FD_SETSIZE; $i++)
> {
> if ($client[$i] != null)
> $rfds[$i + 1] = $client[$i];
> }
>
>
> // block indefinitely until we receive a connection...
>
> $nready = socket_select($rfds, $null, $null, null);
>
>
> // if we have a new connection, stick it in the $client array,
>
> if (in_array($listenfd, $rfds))
> {
> print "listenfd heard something, setting up new client\n";
>
> for ($i = 0; $i < FD_SETSIZE; $i++)
> {
> if ($client[$i] == null)
> {
> $client[$i] = socket_accept($listenfd);
> socket_setopt($client[$i], SOL_SOCKET, SO_REUSEADDR, 1);
> socket_getpeername($client[$i], $remote_host[$i], $remote_port[$i]);
> print "Accepted {$remote_host[$i]}:{$remote_port[$i]} as
> client[$i]\n";
> break;
> }
>
> if ($i == FD_SETSIZE - 1)
> {
> trigger_error("too many clients", E_USER_ERROR);
> exit;
> }
> }
> if ($i > $maxi)
> $maxi = $i;
>
> if (--$nready <= 0)
> continue;
> }
>
>
> // check the clients for incoming data.
>
> for ($i = 0; $i <= $maxi; $i++)
> {
> if ($client[$i] == null)
> continue;
>
> if (in_array($client[$i], $rfds))
> {
> $n = trim(socket_read($client[$i], MAXLINE));
>
> if (!$n)
> closeClient($i);
> else
> {
> // if a client has sent some data, do one of these:
>
> if ($n == "/killme")
> killDaemon();
> else if ($n == "/quit")
> closeClient($i);
> else
> {
> // print something on the server, then echo the incoming
> // data to all of the clients in the $client array.
>
> print "From {$remote_host[$i]}:{$remote_port[$i]}, client[$i]:
> $n\n";
> for ($j = 0; $j <= $maxi; $j++)
> {
> if ($client[$j] != null)
> socket_write($client[$j], "From client[$i]: $n\r\n");
> }
> }
> }
>
> if (--$nready <= 0)
> break;
> }
> }
> }
>
> ?>
>
> ----
>
> --
> PHP Development Mailing List <http://www.php.net/>
> To unsubscribe, visit: http://www.php.net/unsub.php