I'm coding a php socket server script which is running on ubuntu.
It works well, clients can connect/disconnect to this server.
But the server is shutting down silently when a client connect to this server that didn't have any client connected for a long time.
I setted up timeout to 0 (unlimited) but the server is stoping without any errors or messages... like this.
root#exfl:/home/projectap/sec/server_core# php socket_server.php
[exfl.kr] Starting AbsolutePitch socket server...
[2014.06.21 16:50:58] Server is listening. PID: 6442
[2014.06.21 17:28:48] Client [192.168.0.1:8795] connected to the server.
root#exfl:/home/projectap/sec/server_core#
I coded for this server like this.
<?php
set_time_limit(0);
error_reporting(E_ALL);
ini_set("memory_limit","2048M");
ini_set("max_execution_time", "0");
if(posix_getpid() == true) {
echo "[exfl.kr] Starting AbsolutePitch socket server...\n";
} else {
echo getTimeToStr()."Server is already running.\n";
}
$cSock = array();
$socketsInformation = array();
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
$bind = socket_bind($socket, "0.0.0.0", "24180");
$listen = socket_listen($socket, 5);
echo getTimeToStr()."Server is listening. PID: ".posix_getpid()."\n";
while(true) {
$sockArr = array_merge(array($socket), $cSock);
if(socket_select($sockArr, $tWrite = null, $tExcept = null, null) > 0) {
foreach($sockArr as $sock){
if($sock == $socket){
$tSock = socket_accept($socket);
socket_getpeername($tSock, $sockIp, $sockPort);
array_push($cSock, $tSock);
array_push($socketsInformation, array("SOCKETINDEX"=>(count($cSock)-1), "IP"=>$sockIp, "USERID"=>"", "STATUS"=>"", "AUTH"=>false));
echo getTimeToStr()."Client [".$sockIp.":".$sockPort."] connected to the server.\n";
} else {
...
}
}
}
}
echo getTimeToStr()."Server closed.\n";
...
?>
When the server stops suddenly, it isn't outputing a "Server closed" message..
Please help.
Sorry for my bad English.
You may want to try socket_set_options() with SO_KEEPALIVE. To know more about your options use the socket_get_options page:
https://www.php.net/manual/en/function.socket-get-option.php
To know more about the usage of socket_set_options() use:
https://www.php.net/manual/en/function.socket-set-option.php
Related
My PHP script uses raw socket to capture icmp packets, but actually it falis. the script is as follows:
<?php
$protocal = getprotobyname("icmp");
$socket = socket_create(AF_INET,SOCK_RAW,$protocal) or die("Cannot create socket");
while(true){
$read = array($socket); $write = NULL; $except = NULL;
$select = socket_select($read, $write, $except, $timeout=1, 300*1000);
if ($select === false){
echo "socket_select error";
continue;
}
elseif($select === 0){
echo "SocketSelect time out";
continue;
}
socket_recvfrom($socket, $recv, 65535, 0, $host, $port);
print($recv);
sleep(1);
}
?>
when I run the script on a host AAA with the ip of 192.168.1.72 on an Ethernet LAN ,and I use "ping 192.168.1.72 -t" cmd on another host BBB , the ping cmd can get echo from host AAA, and it is expected that the above running script on host AAA can capture the icmp request packet from BBB and print some message, however actually the script just print 'SocketSelect time out' repeatly .
can someone help to work out what is wrong with the php script ?
My goal is capture messages being generated in real time by a Java server socket and display these messages on the webpage.
I am trying to use php to connect to the socket and receive data from the server. The php client should continuously listen to the server for messages.
Here is my php code
<?php
set_time_limit(0);
$serverAddress=SERVER_ADDRESS;
$serverListeningPort=SERVER_PORT;
//make a connection and get a socket object
if ( ($socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) === FALSE )
{
echo "socket_create() failed: reason: " .socket_strerror(socket_last_error());
}
else
{
echo("socket create was successful");
echo("<br>");
}
echo ("Attempting to connect to host");
echo("<br>");
if ( ($result = socket_connect($socket, $serverAddress, $serverListeningPort)) === FALSE )
{
echo ("socket_connect() failed. Reason:".socket_strerror(socket_last_error($socket)));
}
echo ("Reading response:");
$message="";
while(true)//listen for ever
{
$message=socket_read($socket, 300);
if($message!=='')
{
print_r($message);
}
}
?>
When I load this php page, most of the time I get a 504 gateway time out error. I have verified that the Java server is picking up the client connection.
Sometimes, I get a few messages only and then the page stops getting messages from the server. Not sure why, as I have a while(true) loop.
Am I using the php socket correctly? How can I accomplish my goal.
Thank you
Try adding the below lines at the start of your code. This will output the result to browser as it is generated.
ob_end_flush();
ob_implicit_flush(1);
When using stream_select() on an array which contains the server socket created with stream_socket_server() and also the client sockets it always returns instantly with the server socket selected.
My understanding of stream_select() is that it should only return when the server socket state has changed (or timeout is reached). This should only happen if a new client is trying to connect or one client has sent data.
I have written the following code:
$socket = stream_socket_server("tcp://localhost:8888");
$connections['master'] = $socket;
while(true) {
$w = $e = null;
$r = $connections;
if (stream_select($r, $w, $e, 1) !== false) {
foreach ($r as $socket) {
if ($socket === $connections['master']) {
$conn = stream_socket_accept($socket);
$connections[] = $conn;
} else {
// Handle communication with client...
}
}
}
}
With this, I get a non-stop running loop where $r everytime contains the server socket, but stream_socket_accept() throws an error because there is no client trying to connect.
What am I doing wrong? Or is my understanding about stream_select() wrong?
Issue at Hand: Intercepting a print request and modifying the data within the job to add content to it.
Solution so far: Here's the solution that has worked for the windows xp machines
1. Redirect the default printer to a raw TCP/IP port say 9100.
2. Write a basic socket server which listens on the port 9100 and accepts connections when they occur.
3. Read from the socket and modify the content before writing to a virtual printer which redirects to actual port that the default printer was on.
Problem: Steps 1 and 2 do not seem to work on windows 7.. Can someone please help..?
Here is the socket server code(very basic)...
<?php
// set some variables
$host = "127.0.0.1";
$port = 9100;
// don't timeout!
set_time_limit(0);
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, $host, $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 (true)
{
$connection = #socket_accept($sock);
if ($connection === false)
{
usleep(100);
}elseif ($connection > 0)
{
//handle_client($sock, $connection);
}else
{
echo "error: ".socket_strerror($connection);
die;
}
}
So at this point, when a print job happens to a default printer, the server should accept the connection but that is not the case. A basic socket client which performs a socket_create, socket_connect and sends a socket_write works fine.. But the same thing does not happen when a print job to the same port is being sent. It works fine on windows XP. Can someone please help?
Found that on windows 7 IPV6 sockets are used by printers by default. If you run a microsoft fixit to prefer IPV4 over IPV6 or create a IPV6 socket it should work. – user2693294
I created a PHP Socket Server with PHP_NORMAL_READ mode. So, a message to the server is read when it ends with \n or \r. I tried it by connecting to the server with multiple telnet instances, and it works great.
However, when I connect to the server with 1 flash application and 1 telnet application (I first start the flash one), the flash one seems to make the server hang - the server is getting stuck somewhere and no longer receiving data from eg. the telnet client.
Because anyone can code a flash client, this has to be fixed server side. The server's code:
<?php
// config
$timelimit = 60; // amount of seconds the server should run for, 0 = run indefintely
$port = 9000; // the port to listen on
$address = $_SERVER['SERVER_ADDR']; // the server's external IP
$backlog = SOMAXCONN; // the maximum of backlog incoming connections that will be queued for processing
// configure custom PHP settings
error_reporting(1); // report all errors
ini_set('display_errors', 1); // display all errors
set_time_limit($timelimit); // timeout after x seconds
ob_implicit_flush(); // results in a flush operation after every output call
//create master IPv4 based TCP socket
if (!($master = socket_create(AF_INET, SOCK_STREAM, SOL_TCP))) die("Could not create master socket, error: ".socket_strerror(socket_last_error()));
// set socket options (local addresses can be reused)
if (!socket_set_option($master, SOL_SOCKET, SO_REUSEADDR, 1)) die("Could not set socket options, error: ".socket_strerror(socket_last_error()));
// bind to socket server
if (!socket_bind($master, $address, $port)) die("Could not bind to socket server, error: ".socket_strerror(socket_last_error()));
// start listening
if (!socket_listen($master, $backlog)) die("Could not start listening to socket, error: ".socket_strerror(socket_last_error()));
//display startup information
echo "[".date('Y-m-d H:i:s')."] SERVER CREATED (MAXCONN: ".SOMAXCONN.").\n"; //max connections is a kernel variable and can be adjusted with sysctl
echo "[".date('Y-m-d H:i:s')."] Listening on ".$address.":".$port.".\n";
$time = time(); //set startup timestamp
// init read sockets array
$read_sockets = array($master);
// continuously handle incoming socket messages, or close if time limit has been reached
while ((!$timelimit) or (time() - $time < $timelimit)) {
$changed_sockets = $read_sockets;
socket_select($changed_sockets, $write = null, $except = null, null);
foreach($changed_sockets as $socket) {
if ($socket == $master) {
if (($client = socket_accept($master)) < 0) {
continue;
} else {
array_push($read_sockets, $client);
}
} else {
$data = #socket_read($socket, 1024, PHP_NORMAL_READ); //read a maximum of 1024 bytes until a new line has been sent
if ($data === false) { //the client disconnected
$index = array_search($socket, $read_sockets);
unset($read_sockets[$index]);
socket_close($socket);
} elseif ($data = trim($data)) { //remove whitespace and continue only if the message is not empty
echo "we received: ".$data."\n\n";
//handleData($data, $socket);
}
}
}
}
socket_close($master); //close the socket
echo "[".date('Y-m-d H:i:s')."] SERVER CLOSED.\n";
//function to write to the flash client
function flash_write($socket, $msg) {
socket_write($socket, $msg.chr(0x0));
}
?>
Does anyone know what may cause this? I tried changing the timeout on the socket_select from none to 0 (instant return), but that didn't seem to change anything.
Could you post the source of the flash client? That would show what the problem is?
Are you sure the last thing you send from the flash client is a \n ?
Otherwise the server would block on socket_read() as the flash client socket can be read without blocking (triggered socket_select()), but doesn't send the ending \n.
One thing to help you debug: error_reporting(1) does not enable the display of all errors. Look at the documentation at http://us3.php.net/manual/en/function.error-reporting.php. You need something like error_reporting(E_ALL).