socket_accept

(PHP 4 >= 4.1.0, PHP 5)

socket_acceptПринимает соединение на сокете

Описание

resource socket_accept ( resource $socket )

После того, как сокет socket был создан при помощи функции socket_create(), привязан к имени при помощи функции socket_bind(), и ему было указано слушать соединения при помощи функции socket_listen(), эта функция будет принимать входящие соединения на этом сокете. Как только произошло удачное соединение, возвращается новый ресурс сокета, который может быть использован для связи. Если в очереди сокета есть несколько соединений, будет использовано первое из них. Если нету ожидающих соединений, то функция socket_accept() будет блокировать выполнение скрипта до тех пор, пока не появится соединение. Если сокет socket был сделан неблокирующим при помощи функции socket_set_blocking() или socket_set_nonblock(), будет возвращено FALSE.

Ресурс сокета, полученный при помощи функции socket_accept() не может быть использован для принятия новых соединений. Однако изначальный слушающий сокет socket, остаётся открытым и может быть использован повторно.

Список параметров

socket

Действительный ресурс сокета, созданный при помощи функции socket_create().

Возвращаемые значения

В случае успеха возвращает новый ресурс сокета или FALSE в случае ошибки. Код ошибки может быть получен при помощи вызова функции socket_last_error(). Этот код ошибки может быть передан функции socket_strerror() для получения текстового описания ошибки.

Смотрите также

Коментарии

Автор:
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.
2003-12-11 14:49:14
http://php5.kiev.ua/manual/ru/function.socket-accept.html
>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
2005-05-16 11:11:25
http://php5.kiev.ua/manual/ru/function.socket-accept.html
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.
2007-05-22 12:15:16
http://php5.kiev.ua/manual/ru/function.socket-accept.html
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(6553465534);

/* 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_INETSOCK_STREAM0)) < 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) ) < )
    {
        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();

    }
}

?>
2008-01-29 06:35:53
http://php5.kiev.ua/manual/ru/function.socket-accept.html
Автор:
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;
    }
}

?>
2008-04-18 12:01:29
http://php5.kiev.ua/manual/ru/function.socket-accept.html
In order to make many clients connectable to the server, you have to set the accepted socket also to non-blocking. Otherwise the accepted connection will block further incoming connections.

while (true) {
    $newSock = @socket_accept($sock);

    if ($newSock) {
        echo 'client connected';

        socket_set_nonblock($newSock);
    }
}
2014-05-18 17:47:30
http://php5.kiev.ua/manual/ru/function.socket-accept.html
<explain>
 This case is a very simple interaction between the TCP client side and the TCP server side

<?php
// create for simple-tcp-server
$sock socket_create(AF_INETSOCK_STREAMgetprotobyname('tcp'));
socket_bind($sock'127.0.0.1',5000);
socket_listen($sock,1);
$clnt_sock socket_accept($sock); //阻塞
$st "hello world ^_^";
socket_write($clnt_sock$st,strlen($st));
socket_close($clnt_sock);
socket_close($sock);
?>

<?php
//create for simple-tcp-client     
$clnt_sock socket_create(AF_INETSOCK_STREAMgetprotobyname('tcp'));
socket_connect($clnt_sock'127.0.0.1'5000);
$retsocket_read($clnt_sock1024);
print 
"from simple-tcp-server:".$ret.PHP_EOL;
socket_close($clnt_sock);
?>

<fruit>
from simple-tcp-server:hello world ^_^
2019-04-07 09:25:28
http://php5.kiev.ua/manual/ru/function.socket-accept.html

    Поддержать сайт на родительском проекте КГБ