PHP
downloads | documentation | faq | getting help | mailing lists | licenses | wiki | reporting bugs | php.net sites | links | conferences | my php.net

search for in the

socket_bind> <ソケット 関数
Last updated: Fri, 30 Jan 2009

view this page in

socket_accept

(PHP 4 >= 4.1.0, PHP 5)

socket_acceptソケットへの接続を許可する

説明

resource socket_accept ( resource $socket )

socket_create() を使用してソケット socket を作成した後、 socket_bind() で名前に関連付け、 socket_listen() で接続をモニタします。この関数は、 このソケットへの接続を許可します。接続に成功すると、新規の ソケット記述子が返されます。この記述子は通信の際に使用されます。 ソケット上に複数の接続がキューで待っている場合、最初の接続が使用 されます。接続待ちがない場合、socket_accept() は接続が存在するまでブロックされます。 socketsocket_set_blocking() または socket_set_nonblock() により非ブロックモードで 作成された場合、FALSE が返されます。

socket_accept() により返されたソケットリソースは、 新規接続を許可するために使用することはできません。この場合でも 元の接続待ちのソケット socket は オープンされたままであり、再使用可能です。

パラメータ

socket

socket_create() で作成したソケットリソース。

返り値

成功した場合に新規ソケットリソースを、エラー時に FALSE を返します。 実際のエラーコードは、socket_last_error() を コールすることで取得可能です。このコードを socket_strerror() に渡すことで、 エラーの内容を文字列で取得することが可能です。

参考



socket_bind> <ソケット 関数
Last updated: Fri, 30 Jan 2009
 
add a note add a note User Contributed Notes
socket_accept
Anonymous
10-May-2008 02:32
If you want to know the remote address ( ip address ) and the port of an incoming connection that has been accepted with socket_accept(), you can use socket_getpeername()
Boylett
18-Apr-2008 07:01
If you want to have multiple clients on a server you will have to use non blocking.

<?php

$clients
= array();
$socket = socket_create(AF_INET,SOCK_STREAM,SOL_TCP);
socket_bind($socket,'127.0.0.1',$port);
socket_listen($socket);
socket_set_nonblock($socket);

while(
true)
{
    if((
$newc = socket_accept($socket)) !== false)
    {
        echo
"Client $newc has connected\n";
       
$clients[] = $newc;
    }
}

?>
lars at opdenkamp dot eu
29-Jan-2008 02:35
If you want to make a daemon process that forks on each client connection, you'll find out that there's a bug in PHP. The child processes send SIGCHLD to their parent when they exit but the parent can't handle signals while it's waiting for socket_accept (blocking).

Here is a piece of code that makes a non-blocking forking server.

#!/usr/bin/php -q
<?php
/**
  * Listens for requests and forks on each connection
  */

$__server_listening = true;

error_reporting(E_ALL);
set_time_limit(0);
ob_implicit_flush();
declare(
ticks = 1);

become_daemon();

/* nobody/nogroup, change to your host's uid/gid of the non-priv user */
change_identity(65534, 65534);

/* handle signals */
pcntl_signal(SIGTERM, 'sig_handler');
pcntl_signal(SIGINT, 'sig_handler');
pcntl_signal(SIGCHLD, 'sig_handler');

/* change this to your own host / port */
server_loop("127.0.0.1", 1234);

/**
  * Change the identity to a non-priv user
  */
function change_identity( $uid, $gid )
{
    if( !
posix_setgid( $gid ) )
    {
        print
"Unable to setgid to " . $gid . "!\n";
        exit;
    }

    if( !
posix_setuid( $uid ) )
    {
        print
"Unable to setuid to " . $uid . "!\n";
        exit;
    }
}

/**
  * Creates a server socket and listens for incoming client connections
  * @param string $address The address to listen on
  * @param int $port The port to listen on
  */
function server_loop($address, $port)
{
    GLOBAL
$__server_listening;

    if((
$sock = socket_create(AF_INET, SOCK_STREAM, 0)) < 0)
    {
        echo
"failed to create socket: ".socket_strerror($sock)."\n";
        exit();
    }

    if((
$ret = socket_bind($sock, $address, $port)) < 0)
    {
        echo
"failed to bind socket: ".socket_strerror($ret)."\n";
        exit();
    }

    if( (
$ret = socket_listen( $sock, 0 ) ) < 0 )
    {
        echo
"failed to listen to socket: ".socket_strerror($ret)."\n";
        exit();
    }

   
socket_set_nonblock($sock);
   
    echo
"waiting for clients to connect\n";

    while (
$__server_listening)
    {
       
$connection = @socket_accept($sock);
        if (
$connection === false)
        {
           
usleep(100);
        }elseif (
$connection > 0)
        {
           
handle_client($sock, $connection);
        }else
        {
            echo
"error: ".socket_strerror($connection);
            die;
        }
    }
}

/**
  * Signal handler
  */
function sig_handler($sig)
{
    switch(
$sig)
    {
        case
SIGTERM:
        case
SIGINT:
            exit();
        break;

        case
SIGCHLD:
           
pcntl_waitpid(-1, $status);
        break;
    }
}

/**
  * Handle a new client connection
  */
function handle_client($ssock, $csock)
{
    GLOBAL
$__server_listening;

   
$pid = pcntl_fork();

    if (
$pid == -1)
    {
       
/* fork failed */
       
echo "fork failure!\n";
        die;
    }elseif (
$pid == 0)
    {
       
/* child process */
       
$__server_listening = false;
       
socket_close($ssock);
       
interact($csock);
       
socket_close($csock);
    }else
    {
       
socket_close($csock);
    }
}

function
interact($socket)
{
   
/* TALK TO YOUR CLIENT */
}

/**
  * Become a daemon by forking and closing the parent
  */
function become_daemon()
{
   
$pid = pcntl_fork();
   
    if (
$pid == -1)
    {
       
/* fork failed */
       
echo "fork failure!\n";
        exit();
    }elseif (
$pid)
    {
       
/* close the parent */
       
exit();
    }else
    {
       
/* child becomes our daemon */
       
posix_setsid();
       
chdir('/');
       
umask(0);
        return
posix_getpid();

    }
}

?>
galantonp at yahoo dot com
13-Jun-2007 08:20
socket_accept with timeout, seems to work for me on Apache/1.3.37 (FreeBSD 6.0) PHP/4.4.7.

Adapted from ScriptBlue at nyc dot rr dot com's post under socket_connect.

<?php
$socket
= socket_create(AF_INET,SOCK_STREAM,SOL_TCP);
socket_bind($socket,$address,$port);
socket_listen($socket);

echo
"Waiting for a connection\n";
$conn = false;
switch(@
socket_select($r = array($socket), $w = array($socket), $e = array($socket), 60)) {
    case
2:
        echo
"Connection refused\n";
        break;
    case
1:
        echo
"Connection accepted\n";
       
$conn = @socket_accept($socket);
        break;
    case
0:
        echo
"Connection timed out\n";
        break;
}
   
   
if (
$conn !== false) {
   
// communicate over $conn
}

 
?>
gmkarl at gmail dot com
22-May-2007 07:15
Be aware signal handler functions set with pcntl_signal are not called while a socket is blocking waiting for a connection; the signal is absorbed silently and the handler called when a connection is made.
simon at 180solutions dot com
16-May-2005 06:11
>Accepting a connection using php-sockets:
>
>$fd = socket_create(AF_INET, SOCK_STREAM, 6 /* OR >getprotobyname("TCP")*/);
>
>$PORT = 5000;
>
>socket_bind($fd, "0.0.0.0", $PORT);
>
>while(true)
>{
>$remote_fd = socket_accept($fd);
>
>remote_socket_client_handle($remote_fd);
>
>}
>
>It is simple!

This example doesn't work. You have to call socket_listen($fd) after your bind in order to accept incoming connections.

Simon
Greg MacLellan
11-Dec-2003 10:49
The socket returned by this resource will be non-blocking, regardless of what the listening socket is set to. This is actually true for all FCNTL modifiers.
diogo at transoft dot com dot br
18-Aug-2003 11:32
Accepting a connection using php-sockets:

$fd = socket_create(AF_INET, SOCK_STREAM, 6 /* OR getprotobyname("TCP")*/);

$PORT = 5000;

socket_bind($fd, "0.0.0.0", $PORT);

while(true)
{
$remote_fd = socket_accept($fd);

remote_socket_client_handle($remote_fd);

}

It is simple!

socket_bind> <ソケット 関数
Last updated: Fri, 30 Jan 2009
 
 
show source | credits | sitemap | contact | advertising | mirror sites