Re: Re: Package proposal: Sockets

From: Date: Mon, 24 Mar 2003 18:37:48 +0000
Subject: Re: Re: Package proposal: Sockets
References: 1 2 3 4  Groups: php.pear.dev 
Request: Send a blank email to pear-dev+get-14577@lists.php.net to get a copy of this message
Hi, This server or listen socket is not responsible for that. There should be a socket list / server package for that. And as soon as we have some IPC (or whatever) category with process and thread control packages we can add such implementations with worker threads or processes. bye Michael Bretterklieber wrote:
Hi, Stephan Seidt schrieb:
please think also about implementing server-sockets for supporting more then one client-connection, otherwise server-sockets are not very useful.
Hm, a server socket just means listen socket. The accept call usually returns a server socket. What you mean has to be implemented in some Socket-Server package. It could consist of a socket list, data handling options, etc. Should we call it SOCKET_LISTEN and not SOCKET_SERVER then?
SERVER_SOCKET is ok. But the package should contain any code for handling many server-sockets simultaneously. Each accept call returns a new socket - one per client-connection. There are some ways to handle simultaneous connections: - forking - threading - select() the first two are a bit problematic implementing with PHP, so the only way is to use the select() syscall (=socket_select()). The select() syscalls returns when one of the given descriptors (sockets) is ready for reading, writing or an exception occured. I attached a small prototype, wich demonstrates such implementation, bye, ------------------------------------------------------------------------ <?php set_time_limit(0); ob_implicit_flush(); $listener = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); if (!is_resource($listener)) { printf("socket_create: %d %s\n", socket_last_error(), socket_strerror(socket_last_error())); exit; } if (!socket_bind($listener, 0,8888)) { printf("socket_bind: %d %s\n", socket_last_error(), socket_strerror(socket_last_error())); exit; } if (!socket_listen($listener, 5)) { printf("socket_listen: %d %s\n", socket_last_error(), socket_strerror(socket_last_error())); exit; } if (!socket_set_nonblock($listener)) { printf("socket_set_nonblock: %d %s\n", socket_last_error(), socket_strerror(socket_last_error())); exit; } $sockets = array($listener); $read = $sockets; while(true) { if (($geaendert = socket_select($read, $write = NULL, $except = NULL, $timeout = NULL)) === false) { printf("socket_select: %d %s\n", socket_last_error(), socket_strerror(socket_last_error())); } else if ($geaendert > 0) { foreach ($read as $socket) { if ($socket == $listener) { $srvsock = @socket_accept($listener); if (!$srvsock) { if (socket_last_error() == 10035) { // nothing todo } else { printf("socket_accept: %d %s\n", socket_last_error(), socket_strerror(socket_last_error())); } } else { socket_getpeername($srvsock, $addr, $port); printf ("Neue Verbindung von %s:%d\n", $addr, $port); socket_set_nonblock($srvsock); $sockets[] = $srvsock; } } else { $data = socket_read($socket, 65535, PHP_BINARY_READ); //PHP_NORMAL_READ if ($data === false) { printf("socket_read: %d %s\n", socket_last_error(), socket_strerror(socket_last_error())); } else if ($data === '') { // remove socket from our list foreach($sockets as $s) { if ($s != $socket) { $newsockets[] = $s; } else { socket_getpeername($s, $addr, $port); printf("Verbindung von %s:%d beendet\n", $addr, $port); } } socket_close($socket); $sockets = $newsockets; } else { socket_getpeername($socket, $addr, $port); printf ('Empfange von %s:%d:%s', $addr, $port, $data); if (preg_match('/who/', $data)) { foreach($sockets as $sock2) { if ($sock2 != $listener && $sock2 != $socket) { socket_getpeername($sock2, $addr, $port); socket_write($socket, "$addr:$port\n"); } } } else if (preg_match('/ping/', $data)) { socket_write($socket, "pong\n"); } } } } $read = $sockets; } } echo "accept\n"; socket_close($sock); socket_close($listener); ?>


« previous php.pear.dev (#14577) next »