Delicious Bookmark this on Delicious Share on Facebook SlashdotSlashdot It! Digg! Digg



PHP : Function Reference : Stream Functions : stream_socket_server

stream_socket_server

Create an Internet or Unix domain server socket (PHP 5)
resource stream_socket_server ( string local_socket [, int &errno [, string &errstr [, int flags [, resource context]]]] )

Creates a stream or datagram socket on the specified local_socket. The type of socket created is determined by the transport specified using standard URL formatting: transport://target. For Internet Domain sockets (AF_INET) such as TCP and UDP, the target portion of the remote_socket parameter should consist of a hostname or IP address followed by a colon and a port number. For Unix domain sockets, the target portion should point to the socket file on the filesystem. flags is a bitmask field which may be set to any combination of socket creation flags. The default value of flags is STREAM_SERVER_BIND | STREAM_SERVER_LISTEN.

Note:

For UDP sockets, you must use STREAM_SERVER_BIND as the flags parameter.

This function only creates a socket, to begin accepting connections use stream_socket_accept().

If the call fails, it will return FALSE and if the optional errno and errstr arguments are present they will be set to indicate the actual system level error that occurred in the system-level socket(), bind(), and listen() calls. If the value returned in errno is 0 and the function returned FALSE, it is an indication that the error occurred before the bind() call. This is most likely due to a problem initializing the socket. Note that the errno and errstr arguments will always be passed by reference.

Depending on the environment, Unix domain sockets may not be available. A list of available transports can be retrieved using stream_get_transports(). See Appendix Q, List of Supported Socket Transports for a list of bulitin transports.

Example 2391. Using TCP server sockets

<?php
$socket
= stream_socket_server("tcp://0.0.0.0:8000", $errno, $errstr);
if (!
$socket) {
 echo
"$errstr ($errno)<br />\n";
} else {
 while (
$conn = stream_socket_accept($socket)) {
   
fwrite($conn, 'The local time is ' . date('n/j/Y g:i a') . "\n");
   
fclose($conn);
 }
 
fclose($socket);
}
?>


The example below shows how to act as a time server which can respond to time queries as shown in an example on stream_socket_client().

Note:

Most systems require root access to create a server socket on a port below 1024.

Example 2392. Using UDP server sockets

<?php
$socket
= stream_socket_server("udp://127.0.0.1:1113", $errno, $errstr, STREAM_SERVER_BIND);
if (!
$socket) {
   die(
"$errstr ($errno)");
}

do {
   
$pkt = stream_socket_recvfrom($socket, 1, 0, $peer);
   echo
"$peer\n";
   
stream_socket_sendto($socket, date("D M j H:i:s Y\r\n"), 0, $peer);
} while (
$pkt !== false);

?>


Note:

When specifying a numerical IPv6 address (e.g. fe80::1) you must enclose the IP in square brackets. For example, tcp://[fe80::1]:80.

See also stream_socket_client(), stream_set_blocking(), stream_set_timeout(), fgets(), fgetss(), fwrite(), fclose(), feof(), and the Curl extension.

Code Examples / Notes » stream_socket_server

andrey

Just a small example how to use this function and also stream_select() to make a server that accepts more than one connections (can have many clients connected):
In master we hold all opened connections. Just before calling stream select we copy the array to $read and then pass it ot stream_select(). In case that we may read from at least one socket, $read will contain socket descriptors. $master is needed not to lose references to the opened connections we have.
stream_server.php :
<?php
$master = array();
$socket = stream_socket_server("tcp://0.0.0.0:8000", $errno, $errstr);
if (!$socket) {
echo "$errstr ($errno)<br />\n";
} else {
$master[] = $socket;
$read = $master;
while (1) {
$read = $master;
$mod_fd = stream_select($read, $_w = NULL, $_e = NULL, 5);
if ($mod_fd === FALSE) {
break;
}
for ($i = 0; $i < $mod_fd; ++$i) {
if ($read[$i] === $socket) {
$conn = stream_socket_accept($socket);
fwrite($conn, "Hello! The time is ".date("n/j/Y g:i a")."\n");
$master[] = $conn;
} else {
$sock_data = fread($read[$i], 1024);
var_dump($sock_data);
if (strlen($sock_data) === 0) { // connection closed
$key_to_del = array_search($read[$i], $master, TRUE);
fclose($read[$i]);
unset($master[$key_to_del]);
} else if ($sock_data === FALSE) {
echo "Something bad happened";
$key_to_del = array_search($read[$i], $master, TRUE);
unset($master[$key_to_del]);
} else {
echo "The client has sent :"; var_dump($sock_data);
fwrite($read[$i], "You have sent :[".$sock_data."]\n");
fclose($read[$i]);
unset($master[array_search($read[$i], $master)]);
}
}
}
}
}
?>
stream_client.php:
<?php
$fp = stream_socket_client("tcp://127.0.0.1:8000", $errno, $errstr, 30);
if (!$fp) {
echo "$errstr ($errno)<br />\n";
} else {
fwrite($fp, "Aloha");
while (!feof($fp)) {
var_dump(fgets($fp, 1024));
}
fclose($fp);
}
?>
Thanks


neil munro

If you want a high speed socket server, use the low-level sockets instead (socket_create/bind/listen). The stream_socket_server version appears to have internal fixed 8k buffers that will overflow if you don't keep up by reading.
This is a serious problem if you an application that reads the socket for messages and then, say, saves the result in a database. The delay while it is busy processing means you can't read the data in time unless you get involved in muti-threading.
With the the low-level functions, the OS quietly buffers TCP/IP packets so there is no problem (tested on Windows XP Professional).


e

Example "Hello World!" SSL HTTP Server. Note, if you don't use a signed ssl certificate, your browser will give you a warning.
<?php
// Hello World! SSL HTTP Server.
// Tested on PHP 5.1.2-1+b1 (cli) (built: Mar 20 2006 04:17:24)
$context = stream_context_create();
// local_cert must be in PEM format
stream_context_set_option($context, 'ssl', 'local_cert', './server.pem');
// Pass Phrase (password) of private key
stream_context_set_option($context, 'ssl', 'passphrase', 'comet');
stream_context_set_option($context, 'ssl', 'allow_self_signed', true);
stream_context_set_option($context, 'ssl', 'verify_peer', false);
// Create the server socket
$server = stream_socket_server('ssl://0.0.0.0:9001', $errno, $errstr, STREAM_SERVER_BIND|STREAM_SERVER_LISTEN, $context);
while(true)
{
$buffer = '';
print "waiting...";
$client = stream_socket_accept($server);
print "accepted " . stream_socket_get_name( $client, true) . "\n";
if( $client )
{
// Read until double CRLF
while( !preg_match('/\r?\n\r?\n/', $buffer) )
$buffer .= fread($client, 2046);
// Respond to client
fwrite($client,  "200 OK HTTP/1.1\r\n"
. "Connection: close\r\n"
. "Content-Type: text/html\r\n"
. "\r\n"
. "Hello World! " . microtime(true)
. "<pre>{$buffer}</pre>");
fclose($client);
} else {
print "error.\n";
}
}
// Example PEM File below (call it server.pem, to use this example)
// Use these instructions to create your own. http://sial.org/howto/openssl/self-signed/
/*
-----BEGIN CERTIFICATE-----
MIIDgTCCAuqgAwIBAgIJAMgtIWVzb1oIMA0GCSqGSIb3DQEBBQUAMIGIMQswCQYD
VQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEUMBIGA1UEBxMLTG9zIEFuZ2Vs
ZXMxFDASBgNVBAoTC091ciBDb21wYW55MQ0wCwYDVQQLEwRUZXN0MQwwCgYDVQQD
EwNEZXYxGzAZBgkqhkiG9w0BCQEWDGFzZEBob3N0LmNvbTAeFw0wNjA1MjYwMTM4
NTRaFw0wNzA1MjYwMTM4NTRaMIGIMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2Fs
aWZvcm5pYTEUMBIGA1UEBxMLTG9zIEFuZ2VsZXMxFDASBgNVBAoTC091ciBDb21w
YW55MQ0wCwYDVQQLEwRUZXN0MQwwCgYDVQQDEwNEZXYxGzAZBgkqhkiG9w0BCQEW
DGFzZEBob3N0LmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA3mStTm74
kOQCelquoGI/WyUIOvngDdNcJGmi2xnzDpRjKfQTH/3VVDQJUwvjKcLxnBQHFg7M
nvEZrfC3LEmFajAzRKjXK5gUCQEQKqhbVsfZO+7ANq4axNldd4UgMhPeZIKr8DDt
P3pjFqFSYh/dtOq2pfDXSbstmCZ1Q3GAYDcCAwEAAaOB8DCB7TAdBgNVHQ4EFgQU
WQSzc00pkM9aCzsxKJpTYm3kwEUwgb0GA1UdIwSBtTCBsoAUWQSzc00pkM9aCzsx
KJpTYm3kwEWhgY6kgYswgYgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9y
bmlhMRQwEgYDVQQHEwtMb3MgQW5nZWxlczEUMBIGA1UEChMLT3VyIENvbXBhbnkx
DTALBgNVBAsTBFRlc3QxDDAKBgNVBAMTA0RldjEbMBkGCSqGSIb3DQEJARYMYXNk
QGhvc3QuY29tggkAyC0hZXNvWggwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUF
AAOBgQA7G/XKQ9kLTZOcVAG/IOxdn9tW38sEwHifNQ7zMSS5di1MmnD5JJWdK/s4
dzN06T1Ey5FCu2kafFzk48khZpoPsXMRF8DNBXLVSCGj4maPtEviJVjwtj3XwZjA
82a8A/Yil0+fo25zPX4I4oBcbl3bPqzVPXxsQ7myp9f7MDZcbQ==
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,E4476A175B6608B6
r0sox8H5ijuOanXwYFtIDgPti3AAuIUdy5EJG9GZbrtQHEW6HL+YxdI58Ng70t4w
EfBvcuLb7XAGsJwF65yad0vSXsYv6F+0brEefEvZX3ljxUZ3yGfHVJyEdBWJty7X
A8QpqOVVQseAST1IKeWOIT16/a9ZOgwnIhQe36y43pxBwL5tumXTM+AuWPOBW8c0
s49I8GyptttGJpcFohLsmP9Jza/fMIzYFNeuOBQ93fieCcVXBd2fWNyZVEsOU5Mi
kt5FQ9Lc9F8Wc+Mh0xiodDz6H+2yNIMC2SNu/mDSAGwDCctBZ34enFDad/eBiYW+
iTjMaqWGFs+cantSgVQ6pdZWYQd5Rsb3/Qbcfia/C1vtzWipBG7wlQCsNWwceXx/
f8hqWl5kyCxvBdH9eyRNMVJkCbFABl9tnaMGRi/UnVL68wgUvosAsdCjUrdL3x7O
i6yMBrxYjACbYslPFaG5OtgXcbacBKjsVMkcRYRyGqClgVZHICYZXhZoZTjOsgT4
L9WivT1RnozmFUMPaXbnxX4h/B3v6aSYAc4mPM6oMFTiXGJ7cLoafNw7Fxug7oeF
0+04DykzFCsLw1PmnkXP/WliQ+xidKJeKl2bR0k5MjAs0ksjelk7hAbCDjE0ct0w
LAHuvf6haClaFBa0ugL90S6BBdIQad9GRmAqZlVc5tANZleXFEY2wKUSMddIKzsm
nouipBWt3flDyYaFRtF20IYYk59z3zlqk73U/cFRkpT9SvHbxdsjTX1OvsmuhMzV
5K4+1QaBK4vePOFeEHDAkwGGqI1Wj+2lC6pxdLe3tjIzNWN1eaq59Q==
-----END RSA PRIVATE KEY-----

*/
?>


Change Language


Follow Navioo On Twitter
stream_bucket_append
stream_bucket_make_writeable
stream_bucket_new
stream_bucket_prepend
stream_context_create
stream_context_get_default
stream_context_get_options
stream_context_set_option
stream_context_set_params
stream_copy_to_stream
stream_encoding
stream_filter_append
stream_filter_prepend
stream_filter_register
stream_filter_remove
stream_get_contents
stream_get_filters
stream_get_line
stream_get_meta_data
stream_get_transports
stream_get_wrappers
stream_register_wrapper
stream_resolve_include_path
stream_select
stream_set_blocking
stream_set_timeout
stream_set_write_buffer
stream_socket_accept
stream_socket_client
stream_socket_enable_crypto
stream_socket_get_name
stream_socket_pair
stream_socket_recvfrom
stream_socket_sendto
stream_socket_server
stream_socket_shutdown
stream_wrapper_register
stream_wrapper_restore
stream_wrapper_unregister
eXTReMe Tracker