I am running script server.php where I am listening to IP and PORT. I simulate incoming message by running input.php.
Question: How can I listen to every port?
Note: I am trying to catch any message, that will go via TCP/IP protocol to my IP regardless on which port.
server.php
function writeToFile($strFilename, $strText)
{
if ($fp = #fopen($strFilename, "a+")) {
$contents = fwrite($fp, $strText . PHP_EOL);
fclose($fp);
return true;
} else {
return false;
}
}
$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
$bind = socket_bind($sock, $address, $port);
socket_listen($sock, 5);
while ($con == 1) {
$client = socket_accept($sock);
$input = socket_read($client, 100);
$prefix = date('Y_m_d');
$data = $prefix . '_data.txt';
writeToFile($data, $input);
if ($input == 'exit') {
socket_close($sock);
$con = 0;
}
if ($con == 1) {
$word .= $input;
}
echo $input . PHP_EOL;
socket_write($client, $input . PHP_EOL);
}
input.php
<?php
$address = "192.168.0.103";
$port = 5503;
$randomString = substr(str_shuffle("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), 0, 10);
$fp = fsockopen($address, $port);
$bytes = fwrite($fp, $randomString);
if ($bytes == false) {
echo 'Send data: 0 Bytes';
} else {
echo 'Send data: ' . $bytes . ' Bytes';
}
fclose($fp);
exit;
Listening to all ports by creating a socket is not a good idea. Better monitor incoming SYN (synchronize) request and then bind to that particular port.
You can use tcpdump for monitoring incoming requests.
tcpdump -i eth0 -s 1500 port not 22 and '(tcp-syn|tcp-ack)!=0'
You can exclude ports by port not. Make sure to use correct interface name.
Execute above command with php function proc_open, since tcpdump gives continuous output.
$cmd = 'tcpdump -i eth1 -s 1500 port not 22 and "(tcp-syn|tcp-ack)!=0"';
$descriptorspec = array(
0 => array("pipe", "r"), // stdin is a pipe that the child will read from
1 => array("pipe", "w"), // stdout is a pipe that the child will write to
2 => array("pipe", "w") // stderr is a pipe that the child will write to
);
flush();
$process = proc_open($cmd, $descriptorspec, $pipes, realpath('./'), array());
if (is_resource($process)) {
while ($s = fgets($pipes[1])) {
print $s;
//make sure $s is a SYN request then create and listen to port
flush();
}
}
Related
I've written a pair of PHP socket servers that listen around for commands and respond to them. The problem is that they do so by listening in an infinite loop, and thus are eating up CPU.
So how do I do this (1) without eating up CPU; and (2) without slowing down the socket commands, particularly if I have several come in in sequence?
$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_set_option($sock, SOL_SOCKET, SO_REUSEADDR, 1);
socket_bind($sock, $address, $port);
socket_listen($sock);
$clients = array($sock);
$write = NULL;
$except = NULL;
while (true) {
$read = $clients;
if (socket_select($read, $write, $except, 0) < 1)
continue;
if (in_array($sock, $read)) {
$clients[] = socket_accept($sock);
$key = array_search($sock, $read);
unset($read[$key]);
}
foreach ($read as $read_sock) {
/* I tried putting a tiny sleep here, but if I run several socket connections for the same user sequentially, they see a notable slowdown */
$data = #socket_read($read_sock, 1024, PHP_NORMAL_READ);
if ($data === false) {
$key = array_search($read_sock, $clients);
unset($clients[$key]);
echo "client disconnected.\n";
continue;
}
$data = trim($data);
/* And this is the heart of my loop */
}
} // end of reading foreach
}
// close the listening socket
socket_close($sock);
i have implemented a socket server in localhost
script i used is from http://www.sanwebe.com/2013/05/chat-using-websocket-php-socket
script is
$host = "localhost"; //host
$port = 9099; //port
if(isset($argv[1]))
{
$host = $argv[1];
}
if(isset($argv[2]))
{
$port = $argv[2];
}
$null = NULL; //null var
$ips=array();
//Create TCP/IP sream socket
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
//reuseable port
socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1);
//bind socket to specified host
socket_bind($socket, 0, $port);
//listen to port
socket_listen($socket);
//create & add listning socket to the list
$clients = array($socket);
$clients_ip=array();
//start endless loop, so that our script doesn't stop
while (true) {
//manage multipal connections
$changed = $clients;
//returns the socket resources in $changed array
socket_select($changed, $null, $null, 0, 10);
//check for new socket
if (in_array($socket, $changed)) {
$socket_new = socket_accept($socket); //accpet new socket
socket_getpeername($socket_new, $ip);
$clients[] = $socket_new; //add socket to client array
$clients_ip[$ip] = $socket_new;
$header = socket_read($socket_new, 1024); //read data sent by the socket
perform_handshaking($header, $socket_new, $host, $port); //perform websocket handshake
//get ip address of connected socket
$ips[]=$ip;
$response = mask(json_encode(array('ip'=>$ip,'type'=>'c', 'message'=>$ip.' connected','ips'=>$ips))); //prepare json data
send_message($response); //notify all users about new connection
//make room for new socket
$found_socket = array_search($socket, $changed);
unset($changed[$found_socket]);
}
//print_r($changed);exit;
if(count($changed)>0)
{
//loop through all connected sockets
foreach ($changed as $changed_socket) {
//check for any incomming data
while(socket_recv($changed_socket, $buf, 1024, 0) >= 1)
{
$received_text = unmask($buf); //unmask data
$tst_msg = json_decode($received_text); //json decode
//$user_name = $tst_msg->name; //sender name
//$user_message = $tst_msg->message; //message text
//$user_color = $tst_msg->color; //color
//prepare data to be sent to clientjson_encode(array('type'=>'usermsg', 'name'=>$user_name, 'message'=>$user_message, 'color'=>$user_color))
$response_text = mask($received_text);
if(isset($tst_msg->type))
{
if($tst_msg->type=="n")
{
#socket_write($clients_ip[$tst_msg->to_ip],$response_text,strlen($response_text));
}
}
//send_message($response_text); //send data
break 2; //exist this loop
}
$buf = #socket_read($changed_socket, 1024, PHP_NORMAL_READ);
if ($buf === false) { // check disconnected client
// remove client for $clients array
$found_socket = array_search($changed_socket, $clients);
socket_getpeername($changed_socket, $ip);
unset($clients[$found_socket]);
if (($key = array_search($ip, $ips)) !== false)
{
unset($ips[$key]);
}
$ips=array_values($ips);
//notify all users about disconnected connection
$response = mask(json_encode(array('ip'=>$ip,'type'=>'d', 'message'=>$ip.' disconnected','ips'=>$ips)));
send_message($response);
}
}
}
}
// close the listening socket
socket_close($sock);
function send_message($msg)
{
global $clients;
foreach($clients as $changed_socket)
{
#socket_write($changed_socket,$msg,strlen($msg));
}
return true;
}
//Unmask incoming framed message
function unmask($text) {
$length = ord($text[1]) & 127;
if($length == 126) {
$masks = substr($text, 4, 4);
$data = substr($text, 8);
}
elseif($length == 127) {
$masks = substr($text, 10, 4);
$data = substr($text, 14);
}
else {
$masks = substr($text, 2, 4);
$data = substr($text, 6);
}
$text = "";
for ($i = 0; $i < strlen($data); ++$i) {
$text .= $data[$i] ^ $masks[$i%4];
}
return $text;
}
//Encode message for transfer to client.
function mask($text)
{
$b1 = 0x80 | (0x1 & 0x0f);
$length = strlen($text);
if($length <= 125)
$header = pack('CC', $b1, $length);
elseif($length > 125 && $length < 65536)
$header = pack('CCn', $b1, 126, $length);
elseif($length >= 65536)
$header = pack('CCNN', $b1, 127, $length);
return $header.$text;
}
//handshake new client.
function perform_handshaking($receved_header,$client_conn, $host, $port)
{
$headers = array();
$lines = preg_split("/\r\n/", $receved_header);
foreach($lines as $line)
{
$line = chop($line);
if(preg_match('/\A(\S+): (.*)\z/', $line, $matches))
{
$headers[$matches[1]] = $matches[2];
}
}
$secKey = $headers['Sec-WebSocket-Key'];
$secAccept = base64_encode(pack('H*', sha1($secKey . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11')));
//hand shaking header
$upgrade = "HTTP/1.1 101 Web Socket Protocol Handshake\r\n" .
"Upgrade: websocket\r\n" .
"Connection: Upgrade\r\n" .
"WebSocket-Origin: $host\r\n" .
"WebSocket-Location: ws://$host:$port/demo/shout.php\r\n".
"Sec-WebSocket-Accept:$secAccept\r\n\r\n";
socket_write($client_conn,$upgrade,strlen($upgrade));
}
i run this program in xampp shell like
php -q path-to-server\server.php
i have a server with shell support
But when i run script
php -q path-to-server\server.php
it works but when shell is closed server will close automatically
so how to run this server continuously with out automatically closing?
i have a linux hosting package
Use this code,
php -f server.php
if you want to run continusely in banground you can use nohub
nohup php server.php &
if want to kill the process you use kill
kill processid
you can run in terminal
php filename.php
I'm guessing you are connecting to the server by ssh?
The server session is ending and all open proccesses are killed that is why your server instance is ending, you are running it from a non-privileged user.
So the way I use is to install screen on the remote server and use that.
https://www.gnu.org/software/screen/manual/screen.html
Or it looks like you might be running a windows server. If this is the case I would recomend using a Linux server as windows makes this a little harder. You will have to run your server instance as a system proccess.
you should run this command as a background proccess like
nohup php -f myBind.php > /dev/null &
Also you can put a simple sccript to crontab for checking your bind.php is up or not if its not run it again.
This is a server client web socket program, when client send "exe" command the server executes a C application.
The output of the c application is read from STDOUT by server and displayed on the client browser.
Now there is a C application that requires a user input(scanf), we saved the input in a txt file. We read the input
and write it to the stdin of the c program. The problem is that it seems that the C program is not accepting the input
that we are writting on the stdin. When i tried this code without any stream select it was working and displaying the sum of two numbers read from input file, but when i place it in stream select command its creating problem. My complete server code is at the end.
a part of server code that is creating child process on a client request
if(strcmp($user_message, "exe") == 0 ) {
echo "Executing a process\n";
$cwd = '/var/www/html/test/websockets' ;
$process = proc_open($exe_command, $descriptorspec, $pipes, $cwd);//creating child process
sleep(1);
if (is_resource($process))
{
echo "Process Created";
$read_socks[] = $pipes[1];//add a descriptor
$stdout = array($pipes[1]);//save stdout in a variable defined above
$stdin = array($pipes[0]);
print_r ($stdout);
print_r ($stdin);
}
}
else
{
echo "Passing value to the C program".$user_message;
//Read input.txt by line and store it in an array
$input = array();
$input = file('/var/www/html/test/websockets/input.txt');
echo "INPUT";
print_r($input);
echo "\n";
//Feed the input (hardcoded)
$bytes = fwrite($stdin[0], "$input[0] $input[1]");
echo "Bytes written:".$bytes;
sleep(1);
}
}
}
add.c
#include <stdio.h>
int main(void)
{
int first, second;
printf("Enter two integers > \n");
scanf("%d", &first);
scanf("%d", &second);
printf("The two numbers are: %d %d\n", first, second);
printf("Output: %d\n", first+second);
}
input.txt
2
4
output
Passing value to the C program3Array
(
[0] => Resource id #11
)
INPUTArray
(
[0] => 2
[1] => 4
)
Bytes written:5
By doing ps I get
root 1173 1164 0 12:08 pts/6 00:00:00 tclsh /usr/bin/unbuffer /var/www/html/test/websockets/./add
root 1174 1173 0 12:08 pts/8 00:00:00 /var/www/html/test/websockets/./add
After bytes written the server is hanging there is no response from the C application i.e the addition result of 4+2.
Why there are two process of add i started 1 with proc open.
complete server code
<?php
execute_prog('unbuffer /var/www/html/test/websockets/./add');//unbuffer stdout
function execute_prog($exe)
{
echo "[+execute_prog]";
$host = 'localhost'; //host
$port = '9000'; //port
$null = NULL; //null var
$read_socks;
$new_client;
$server = stream_socket_server("tcp://0.0.0.0:9000", $errno, $errorMessage);
if ($server === false)
{
throw new UnexpectedValueException("Could not bind to socket: $errorMessage");
}
set_time_limit(1800);
$exe_command = escapeshellcmd($exe);
$descriptorspec = array(
0 => array("pipe", "r"), // stdin -> for execution
1 => array("pipe", "w"), // stdout -> for execution
2 => array("pipe", "w") // stderr
);
// $process = proc_open($exe_command, $descriptorspec, $pipes);//creating child process
// if (is_resource($process))
{
$client_socks = array();
$read_socks = array($server);
$changed = array();
$stdout = NULL;
$stdin = NULL;
while(1)
{
//prepare readable sockets
$write = NULL;
$err = NULL;
$except = NULL;
$changed = $read_socks;//by refrence
/*
echo "stdout:";
print_r ($stdout);
echo "\n";
echo "changed:";
print_r ($changed);
echo "\n";
echo "read sock:";
print_r ($read_socks);
echo "\n";
*/
if (false === ($num_changed_streams = stream_select($changed, $write, $except, 0)))
{
/* Error handling */
echo "Errors\n";
}
else if ($num_changed_streams > 0)
{
/* At least on one of the streams something interesting happened */
echo "Data on ".$num_changed_streams." descriptor\n";
if(in_array($stdout[0], $changed))
{
echo "Data on child process STDOUT\n";
$s = fgets($stdout[0]);
if( $s === false )
{
// Hello program has finished.
echo 'Finished', PHP_EOL;
$s = NULL;
//ob_flush();
flush();
// Close all descriptors and return...
// break;
}
else
{
echo $s."</br>";
//prepare data to be sent to client
$response_text = mask(json_encode(array('type'=>'usermsg', 'name'=>$user_name, 'message'=>$s, 'color'=>$user_color)));
foreach ($read_socks as $sock)
{
if(($sock != $server) && ($sock != $stdout))
fwrite($sock, $response_text, strlen($response_text));
}
$s = NULL;
//ob_flush();
flush();
}
}
else if(in_array($server, $changed))
{
//new client
echo "New Connection\n";
$new_client = stream_socket_accept($server);
if ($new_client)
{
//print remote client information, ip and port number
echo 'Connection accepted from ' . stream_socket_get_name($new_client, true) . "n";
$read_socks[] = $new_client;
echo "Now there are total ". count($read_socks) . " clients.n";
}
$header = fread($new_client, 1024);//read data sent by the socket
perform_handshaking($header, $new_client, $host, $port); //perform websocket handshake
$ip = stream_socket_get_name($new_client, true);
$response = mask(json_encode(array('type'=>'system', 'message'=>$ip.' connected'))); //prepare json data
fwrite($new_client,$response,strlen($response));
//delete the server socket from the read sockets
unset($changed[ array_search($server, $changed) ]);
}
else if($write)
{
echo "Data on child process STDIN\n";
}
else if($err)
{
echo "Data on child process STDERR\n";
}
else
{
echo "Message from the client \n";
//message from existing client
foreach($changed as $sock)
{
$data = fread($sock, 128);
//echo "Data read:".$data." From sock:".$sock."\n";
if(!$data)
{
unset($client_socks[ array_search($sock, $client_socks) ]);
#fclose($sock);
echo "A client disconnected. Now there are total ". count($client_socks) . " clients.n";
continue;
}
else
{
$received_text = unmask($data); //unmask data
$tst_msg = json_decode($received_text); //json decode
$user_name = $tst_msg->name; //sender name
$user_message = $tst_msg->message; //message text
$user_color = $tst_msg->color; //color
//echo "name:".$user_name." user mesg:".$user_message."\n";
//prepare data to be sent to client
$response_text = mask(json_encode(array('type'=>'usermsg', 'name'=>$user_name, 'message'=>$user_message, 'color'=>$user_color)));
fwrite($sock, $response_text, strlen($response_text));
//..................................................................................................................
if(strcmp($user_message, "exe") == 0 )
{
echo "Executing a process\n";
$cwd = '/var/www/html/test/websockets' ;
$process = proc_open($exe_command, $descriptorspec, $pipes, $cwd);//creating child process
sleep(1);
if (is_resource($process))
{
echo "Process Created";
$read_socks[] = $pipes[1];//add a descriptor
$stdout = array($pipes[1]);//save stdout in a variable defined above
$stdin = array($pipes[0]);
print_r ($stdout);
print_r ($stdin);
}
}
else
{
echo "Passing value to the C program".$user_message;
print_r ($stdin);
echo "\n";
//$input = array($user_message);
// fwrite($stdin[0],"$input[0]");//,strlen($user_message));
//Read input.txt by line and store it in an array
$input = array();
$input = file('/var/www/html/test/websockets/input.txt');
echo "INPUT";
print_r($input);
echo "\n";
//Feed the input (hardcoded)
$bytes = fwrite($stdin[0], "$input[0] $input[1]");// $input[1]");
echo "Bytes written:".$bytes;
}
}
}
}
$num_changed_streams = 0;
}
}
// close the listening socket
fclose($server);
fclose($pipes[0]);
fclose($pipes[1]);
fclose($pipes[2]);
echo "exitcode: ".proc_close($process)."\n";
}
echo "[-execute_prog]";
// return $ret;
}
?>
Any ideas how to solve this?
Thank you!
EDIT
The following code writes to the stdin of a C application but when i tried to integrate in the above client server its not working.
<?php
//descriptors to be handled by parent
$descriptorspec = array(
0 => array("pipe", "r"),
1 => array("pipe", "w"),
2 => array("file", "/var/www/html/websockets/error.txt", "a")
);
// define current working directory where files would be stored
$cwd = '/var/www/html' ;
$child_proc = escapeshellcmd("unbuffer /var/www/html/test/websockets/./add");
// $process = proc_open('/var/www/html/websockets/add', $descriptorspec, $pipes);//creating child process
$process = proc_open($child_proc, $descriptorspec, $pipes, $cwd);//creating child process
sleep(1);
if (is_resource($process))
{
//Read input.txt by line and store it in an array
$input = file('/var/www/html/test/websockets/input.txt');
//Feed the input (hardcoded)
fwrite($pipes[0], "$input[0] $input[1]");
fclose($pipes[0]);
while ($s = fgets($pipes[1]))
{
print $s."</br>";
flush();
}
?>
Any guess why the code in the edit part is working where as when integrated in the client server application its output is not as expected.
$child_proc = escapeshellcmd("unbuffer /var/www/html/test/websockets/./add")
the keyword unbuffer was causing the problem although it was there for some other reason but it was the one creating problem.
How to send binary data representing 01 (PHP)?
My Server code (sockets TCP, address is only example. I use my server address of course)
error_reporting(E_ALL);
set_time_limit(0);
ignore_user_abort(true);
$address = '11.111.111.111'; // example server address
$port = 9000; // example port
$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_set_option($sock, SOL_SOCKET, SO_REUSEADDR, 1);
socket_bind($sock, $address, $port);
socket_listen($sock);
$clients = array($sock);
while(true) {
$read = $clients;
if (socket_select($read, $write = NULL, $except = NULL, 0) < 1) {
continue;
}
if (in_array($sock, $read)) {
$clients[] = $newsock = socket_accept($sock);
$key = array_search($sock, $read);
unset($read[$key]);
}
foreach ($read as $read_sock) {
$data = #socket_read($read_sock, 1024);
if ($data === false) {
// remove client for $clients array
$key = array_search($read_sock, $clients);
unset($clients[$key]);
echo "client disconnected.\n";
// continue to the next client to read from, if any
continue;
}
$data = trim($data);
// check if there is any data after trimming off the spaces
if (!empty($data)) {
// send this to all the clients in the $clients array (except the first one, which is a listening socket)
foreach ($clients as $send_sock) {
// if its the listening sock or the client that we got the message from, go to the next one in the list
if ($send_sock == $sock || $send_sock == $read_sock) {
continue;
}
$fp = fopen('socket_communication.txt', 'a');
fwrite($fp, date("Y-m-d H:i:s")." - DATA ".$data."\n");
fclose($fp);
$value = unpack('H*', "1");
$response = base_convert($value[1], 16, 2);
socket_write($send_sock, $response, 1);
} // end of broadcast foreach
}
}
}
echo "Closing sockets...";
socket_close($sock);
I would like to server sent binary data (01 or 1).
I use unpack function and convert it by base_convert but it doesnt works.
This code send response to client
$value = unpack('H*', "1");
$response = base_convert($value[1], 16, 2);
socket_write($send_sock, $response, 1);
i'm trying write asynchronous socket listener code in php. but listener response answer only for first request and for other requests it only can receive packets without response (i'm checking with sniffer) also i'm counting how many time loop was active and loop is active only for first request ...... i'll show my Code :
addr = '192.168.0.117';
$port = 7878;
$sock = socket_create(AF_INET, SOCK_STREAM, 0);
socket_bind($sock, $addr, $port) or die('Could not bind to address');
socket_listen($sock);
$null = NULL;
$clients = Array();
$cc = 0; // loop counter
while(true){
echo $cc."<br>";
$cc = $cc +1;
$read[0] = $sock;
$ready = socket_select($read,$null,$null,$null);
$client = socket_accept($sock);
$input = socket_read($client, 312);
echo $input;
if($input == "exit"){
socket_close($client);
socket_close($sock);
return false;
}
$output = 0x11;
socket_write($client,$output);
$input = "";
}
May be you are closing the listening socket right after the first client sends exit command. You should close only client socket when the client sends exit command. And you return false from the while loop. This means obviously it will process only one client.
if($input == "exit"){
socket_close($client);
socket_close($sock); // Think about this Line.
return false; // Think about this Line.
}