/** * start the server * * @access public */ function start() { if (!function_exists('pcntl_fork')) { return $this->raiseError('Needs pcntl extension to fork processes.', NET_SERVER_ERROR_PCNTL_REQUIRED); } $this->initFD = @socket_create($this->protocol, SOCK_STREAM, 0); if (!$this->initFD) { return $this->raiseError("Could not create socket."); } // adress may be reused socket_setopt($this->initFD, SOL_SOCKET, SO_REUSEADDR, 1); // bind the socket if (!@socket_bind($this->initFD, $this->domain, $this->port)) { $error = $this->getLastSocketError($this->initFd); @socket_close($this->initFD); return $this->raiseError("Could not bind socket to " . $this->domain . " on port " . $this->port . " (" . $error . ")."); } // listen on selected port if (!@socket_listen($this->initFD, $this->maxQueue)) { $error = $this->getLastSocketError($this->initFd); @socket_close($this->initFD); return $this->raiseError("Could not listen (" . $error . ")."); } $this->_sendDebugMessage("Listening on port " . $this->port . ". Server started at " . date("H:i:s", time())); if (method_exists($this->callbackObj, "onStart")) { $this->callbackObj->onStart(); } // Dear children, please do not become zombies pcntl_signal(SIGCHLD, SIG_IGN); // wait for incmoning connections while (true) { // new connection if ($fd = socket_accept($this->initFD)) { $pid = pcntl_fork(); if ($pid == -1) { return $this->raiseError('Could not fork child process.'); } elseif ($pid == 0) { // this is not the parent $this->_isParent = false; // store the new file descriptor $this->clientFD[0] = $fd; $peer_host = ""; $peer_port = ""; socket_getpeername($this->clientFD[0], $peer_host, $peer_port); $this->clientInfo = array("host" => $peer_host, "port" => $peer_port, "connectOn" => time()); $this->_sendDebugMessage("New connection from " . $peer_host . " on port " . $peer_port . ", new pid: " . getmypid()); if (method_exists($this->callbackObj, "onConnect")) { $this->callbackObj->onConnect(0); } $this->serviceRequest(); $this->closeConnection(); exit; } else { // the parent process does not have to do anything } } } }
/** * Bind * * @return bool success * @throws peer.SocketException in case of an error */ public function bind($reuse = false) { if (false === socket_setopt($this->_sock, SOL_SOCKET, SO_REUSEADDR, $reuse) || false === socket_bind($this->_sock, $this->host, $this->port)) { throw new SocketException(sprintf('Binding socket to ' . $this->host . ':' . $this->port . ' failed: %s', $this->getLastError())); } // Update socket host and port socket_getsockname($this->_sock, $this->host, $this->port); return true; }
function acceptConnection(&$socket) { for ($i = 0; $i <= count($this->_server->clientFD); $i++) { if (!isset($this->_server->clientFD[$i]) || $this->_server->clientFD[$i] == null) { $this->_server->clientFD[$i] = socket_accept($socket); socket_setopt($this->_server->clientFD[$i], SOL_SOCKET, SO_REUSEADDR, 1); $peer_host = ""; $peer_port = ""; socket_getpeername($this->_server->clientFD[$i], $peer_host, $peer_port); $this->_server->clientInfo[$i] = array("host" => $peer_host, "port" => $peer_port, "connectOn" => time()); // $this->clients++; $this->_server->_sendDebugMessage("New connection (" . $i . ") from " . $peer_host . " on port " . $peer_port); if (method_exists($this->_server->callbackObj, "onConnect")) { $this->_server->callbackObj->onConnect($i); } return $i; } } }
function run() { if (($sock = socket_create(AF_INET, SOCK_STREAM, 0)) < 0) { return $this->_raiseSoapFault("socket_create() failed: reason: " . socket_strerror($sock)); } if ($this->reuse && !@socket_setopt($sock, SOL_SOCKET, SO_REUSEADDR, 1)) { return $this->_raiseSoapFault("socket_setopt() failed: reason: " . socket_strerror(socket_last_error($sock))); } if (($ret = socket_bind($sock, $this->localaddr, $this->port)) < 0) { return $this->_raiseSoapFault("socket_bind() failed: reason: " . socket_strerror($ret)); } # print "LISTENING on {$this->localaddr}:{$this->port}\n"; if (($ret = socket_listen($sock, $this->listen)) < 0) { return $this->_raiseSoapFault("socket_listen() failed: reason: " . socket_strerror($ret)); } do { $data = NULL; if (($msgsock = socket_accept($sock)) < 0) { $this->_raiseSoapFault("socket_accept() failed: reason: " . socket_strerror($msgsock)); break; } # print "Accepted connection\n"; while ($buf = socket_read($msgsock, 8192)) { if (!($buf = trim($buf))) { continue; } $data .= $buf; } if ($data) { $response = $this->service($data); # write to the socket if (!socket_write($msgsock, $response, strlen($response))) { return $this->_raiseSoapFault('Error sending response data reason ' . socket_strerror()); } } socket_close($msgsock); } while (true); socket_close($sock); }
function run() { if (($sock = socket_create(AF_INET, SOCK_STREAM, 0)) < 0) { return $this->_raiseSoapFault('socket_create() failed. Reason: ' . socket_strerror($sock)); } if ($this->reuse && !@socket_setopt($sock, SOL_SOCKET, SO_REUSEADDR, 1)) { return $this->_raiseSoapFault('socket_setopt() failed. Reason: ' . socket_strerror(socket_last_error($sock))); } if (($ret = socket_bind($sock, $this->localaddr, $this->port)) < 0) { return $this->_raiseSoapFault('socket_bind() failed. Reason: ' . socket_strerror($ret)); } if (($ret = socket_listen($sock, $this->listen)) < 0) { return $this->_raiseSoapFault('socket_listen() failed. Reason: ' . socket_strerror($ret)); } while (true) { $data = null; if (($msgsock = socket_accept($sock)) < 0) { $this->_raiseSoapFault('socket_accept() failed. Reason: ' . socket_strerror($msgsock)); break; } while ($buf = socket_read($msgsock, 8192)) { if (!($buf = trim($buf))) { continue; } $data .= $buf; } if ($data) { $response = $this->service($data); /* Write to the socket. */ if (!socket_write($msgsock, $response, strlen($response))) { return $this->_raiseSoapFault('Error sending response data reason ' . socket_strerror()); } } socket_close($msgsock); } socket_close($sock); }
function socket_set_option($sock, $type, $opt, $value) { socket_setopt($sock, $type, $opt, $value); }
for ($i = 0; $i < FD_SETSIZE; $i++) { if ($client[$i] != null) { $rfds[$i + 1] = $client[$i]; } } // block indefinitely until we receive a connection... $nready = socket_select($rfds, $null, $null, null); // if we have a new connection, stick it in the $client array, if (in_array($listenfd, $rfds)) { if (DEBUG) { print "listenfd heard something, setting up new client\n"; } for ($i = 0; $i < FD_SETSIZE; $i++) { if ($client[$i] == null) { $client[$i] = socket_accept($listenfd); socket_setopt($client[$i], SOL_SOCKET, SO_REUSEADDR, 1); socket_getpeername($client[$i], $remote_host[$i], $remote_port[$i]); if (DEBUG) { print "Accepted {$remote_host[$i]}:{$remote_port[$i]} as client[{$i}]\n"; } break; } if ($i == FD_SETSIZE - 1) { trigger_error("too many clients", E_USER_ERROR); exit; } } if ($i > $maxi) { $maxi = $i; } if (--$nready <= 0) {
/** * Accepts a new connection. * * @param resource $ &$socket socket that received the new connection * @return int $clientID internal ID of the client */ public function acceptConnection(&$socket) { for ($i = 0; $i <= count($this->clientFD); $i++) { if (!isset($this->clientFD[$i]) || $this->clientFD[$i] == null) { $this->clientFD[$i] = socket_accept($socket); socket_setopt($this->clientFD[$i], SOL_SOCKET, SO_REUSEADDR, 1); $peer_host = ""; $peer_port = ""; socket_getpeername($this->clientFD[$i], $peer_host, $peer_port); $this->clientInfo[$i] = array("host" => $peer_host, "port" => $peer_port, "connectOn" => time()); $this->clients++; $this->handler->onConnect($i); return $i; } } }
function init_sockets() { global $CFG; $this->trace('Setting up sockets'); if (false === ($this->listen_socket = socket_create(AF_INET, SOCK_STREAM, 0))) { // Failed to create socket $lasterr = socket_last_error(); $this->fatal('socket_create() failed: ' . socket_strerror($lasterr) . ' [' . $lasterr . ']'); } //socket_close($DAEMON->listen_socket); //die(); if (!socket_bind($this->listen_socket, $CFG->chat_serverip, $CFG->chat_serverport)) { // Failed to bind socket $lasterr = socket_last_error(); $this->fatal('socket_bind() failed: ' . socket_strerror($lasterr) . ' [' . $lasterr . ']'); } if (!socket_listen($this->listen_socket, $CFG->chat_servermax)) { // Failed to get socket to listen $lasterr = socket_last_error(); $this->fatal('socket_listen() failed: ' . socket_strerror($lasterr) . ' [' . $lasterr . ']'); } // Socket has been initialized and is ready $this->trace('Socket opened on port ' . $CFG->chat_serverport); // [pj]: I really must have a good read on sockets. What exactly does this do? // http://www.unixguide.net/network/socketfaq/4.5.shtml is still not enlightening enough for me. socket_setopt($this->listen_socket, SOL_SOCKET, SO_REUSEADDR, 1); socket_set_nonblock($this->listen_socket); }
function _acceptCalls() { $maxi = -1; for ($i = 0; $i < $this->_fd_set_size; $i++) { $this->_clientFD[$i] = null; } while (true) { $rfds[0] =& $this->_sock; for ($i = 0; $i < $this->_fd_set_size; $i++) { if ($this->_clientFD[$i] != null) { $rfds[$i + 1] = $this->_clientFD[$i]; } } // block indefinitely until we receive a connection... $nready = socket_select($rfds, $null, $null, null); // if we have a new connection, stick it in the $client array, if (in_array($this->_sock, $rfds)) { //print "listenfd heard something, setting up new client\n"; for ($i = 0; $i < $this->_fd_set_size; $i++) { if ($this->_clientFD[$i] == null) { $this->_clientFD[$i] = socket_accept($this->_sock); socket_setopt($this->_clientFD[$i], SOL_SOCKET, SO_REUSEADDR, 1); socket_getpeername($this->_clientFD[$i], $this->_remote_host[$i], $this->_remote_port[$i]); if ($i == $this->_fd_set_size - 1) { print "too many clients, refusing {$this->_remote_host[$i]}\n"; socket_write($this->_clientFD[$i], "Sorry, too many clients", 23); $this->_closeClient($i); break; } else { if (!in_array($this->_remote_host[$i], $this->_acl)) { //print ("Refusing {$this->_remote_host[$i]} for ACL rules\n"); socket_write($this->_clientFD[$i], "Permission denied", 17); $this->_closeClient($i); break; } } //print "Accepted {$this->_remote_host[$i]}:{$this->_remote_port[$i]} as client[$i]\n"; $talkback = $this->_help(); socket_write($this->_clientFD[$i], $talkback, strlen($talkback)); break; } } if ($i > $maxi) { $maxi = $i; } if (--$nready <= 0) { continue; } } // check the clients for incoming data. for ($i = 0; $i <= $maxi; $i++) { if ($this->_clientFD[$i] == null) { continue; } if (in_array($this->_clientFD[$i], $rfds)) { $n = trim(socket_read($this->_clientFD[$i], REMOTE_CONSOLE_MAXLINE)); if (!$n) { $this->_closeClient($i); } else { // the request string is $n // build the response and put in $talkback if ($n == 'q') { $this->_closeClient($i); continue; // print the help screen } else { if ($n == 'h') { $talkback = $this->_help(); // quit the whole application } else { if ($n == 'x') { $this->_stopApplication(); break; } else { // Here we manage all user-defined menu entries // if a method exist with the name [choice]actionPerformed() // this method will be executed and return string is sent // back to the client // (for example, if you have a menu like L -> list files in current dir // and you have defined the method LactionPerformed() this // method will be called) $methodName = strtoupper($n) . "actionPerformed"; if (method_exists($this, $methodName)) { $talkback = "\r\n" . $this->{$methodName}() . "\r\n" . $this->_prompt; } else { if (array_key_exists(strtoupper($n), $this->_options)) { $talkback = "Sorry, feature not yet implemented.\r\n" . $this->_prompt; } else { $talkback = "\r\n" . $this->_prompt; } } } } } // send out $talkback to client //print "From {$this->_remote_host[$i]}:{$this->_remote_port[$i]}, client[$i]: $n\n"; if ($this->_clientFD[$i] != null) { socket_write($this->_clientFD[$i], $talkback, strlen($talkback)); } } if (--$nready <= 0) { break; } } } } print time() . " - You should never read this...\n"; exit(1); }
/** * accept a new connection * * @access private * @param resource &$socket socket that received the new connection * @return int $clientID internal ID of the client */ function acceptConnection(&$socket) { for ($i = 0; $i <= count($this->clientFD); $i++) { if (!isset($this->clientFD[$i]) || $this->clientFD[$i] == NULL) { $this->clientFD[$i] = socket_accept($socket); socket_setopt($this->clientFD[$i], SOL_SOCKET, SO_REUSEADDR, 1); $peer_host = ''; $peer_port = ''; socket_getpeername($this->clientFD[$i], $peer_host, $peer_port); $this->clientInfo[$i] = array('host' => $peer_host, 'port' => $peer_port, 'connectOn' => time()); $this->clients++; $this->_sendDebugMessage('New connection (' . $i . ') from ' . $peer_host . ' on port ' . $peer_port); if (method_exists($this->callbackObj, 'onConnect')) { $this->callbackObj->onConnect($i); } return $i; } } }
/** * start the server * * @access public */ function start() { if (!function_exists('pcntl_fork')) { die('Needs pcntl extension to fork processes.'); } $this->initFD = @socket_create($this->protocol, SOCK_STREAM, 0); if (!$this->initFD) { die("Could not create socket."); } // adress may be reused socket_setopt($this->initFD, SOL_SOCKET, SO_REUSEADDR, 1); // bind the socket if (!@socket_bind($this->initFD, $this->domain, $this->port)) { $error = $this->getLastSocketError($this->initFd); @socket_close($this->initFD); die("Could not bind socket to " . $this->domain . " on port " . $this->port . " (" . $error . ")."); } // listen on selected port if (!@socket_listen($this->initFD, $this->maxQueue)) { $error = $this->getLastSocketError($this->initFd); @socket_close($this->initFD); die("Could not listen (" . $error . ")."); } $this->_sendDebugMessage("Listening on port " . $this->port . ". Server started at " . date("H:i:s", time())); if (method_exists($this->callbackObj, "onStart")) { $this->callbackObj->onStart(); } $this->_setDefaultOptions(); $mpmDriverFile = 'Net/Server/Driver/Multiprocess/MPM-' . $this->_mpm . '.php'; if (!@(include_once $mpmDriverFile)) { die('Unknown MPM ' . $mpmDriverFile); } // starting pool of processors... for ($i = 0; $i < $this->_startPool; $i++) { $this->_threadPool[$i] =& new Net_Server_Thread_Processor($i, $this); $this->_threadPool[$i]->start(); print "Started Processor " . $i . " with PID " . $this->_threadPool[$i]->getPid() . "\n"; } // Multi Process Manager $this->_mpmObj =& new MPM($this->_threadPool, $this); $this->_mpmObj->start(); print "Started MPM with PID " . $this->_mpmObj->getPid() . "\n"; // destroy the listening primar socket, it's unuseful at this point @socket_close($this->initFD); // remote console thread $consoleClassName = $this->_console; if (!@(include_once 'Net/Server/Driver/Multiprocess/' . $consoleClassName . '.php')) { die('Unknown console ' . $consoleClassName); } $this->_consoleObj =& new $consoleClassName($this); $this->_consoleObj->start(); print "Started remote console with PID " . $this->_consoleObj->getPid() . "\n"; }