|
 |
stream_socket_server (PHP 5) stream_socket_server --
Create an Internet or Unix domain server socket
Descriptionresource 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.
Замечание:
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
Прил. O for a list of bulitin transports.
Пример 1. 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().
Замечание:
Most systems require root access to create a server socket on a port
below 1024.
Пример 2. 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);
?>
|
|
Замечание: При указании числового адреса IPv6
(например, fe80::1) вы должны заключать его в квадратные скобки. Например,
tcp://[fe80::1]:80.
See also stream_socket_client(),
stream_set_blocking(),
stream_set_timeout(),
fgets(),
fgetss(), fwrite(),
fclose(), feof(), and
the Curl extension.
stream_socket_server
Neil Munro
05-Jul-2006 01:26
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 at osterman dot com
25-May-2006 07:36
Example "Hello World!" SSL HTTP Server. Note, if you don't use a signed ssl certificate, your browser will give you a warning.
<?php
$context = stream_context_create();
stream_context_set_option($context, 'ssl', 'local_cert', './server.pem');
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);
$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 )
{
while( !preg_match('/\r?\n\r?\n/', $buffer) )
$buffer .= fread($client, 2046);
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";
}
}
?>
andrey at php dot net
07-Aug-2004 09:02
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) { $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
| |