Building network services with PHP and xinetd
Not all is web and HTTP. Sometimes we need to create a network service listening to a port. We can create a TCP server in C, Java or even PHP but there’s a really helpful daemon in Linux that helps us to do it. This daemon is xinetd. In this article we are going to create a network service with PHP and xinretd.
Now we are going to create our brand new service with xinetd and PHP. Let’s start. First we are going to create a simple network service listening to 60321 port. Our network service will say hello. The PHP script will be very complicated:
// /home/gonzalo/tests/test1.php echo "HELLO\n";
We want to create a network service on 60321 tcp port so we need to define this port on /etc/services. We put the following line at the end of /etc/services
// /etc/services ... myService 60321/tcp # my hello service
And finally we create out xinetd configuration script on the folder /etc/xinet.d/ , called myService (/etc/xinetd.d/myService)
# default: on
# description: my test service
service myService
{
socket_type = stream
protocol = tcp
wait = no
user = gonzalo
server = /usr/local/bin/php-cli
server_args = /home/gonzalo/tests/test1.php
log_on_success += DURATION
nice = 10
disable = no
}
Now we restart xinetd
sudo /etc/init.d/xinetd restart
And we have our network service ready:
telnet localhost 60321 Trying ::1... Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. HELLO Connection closed by foreign host.
Easy. isn’t it? But it may be not really useful. So we are going to change something in our php script to accept input. Here we cannot use POST or GET parameters (that’s not HTTP) so we need to read input from stdin. In PHP (and in other languajes too) that’s pretty straightforward.
$handle = fopen('php://stdin','r');
$input = fgets($handle);
fclose($handle);
echo "hello {$input}";
Now if we run our script from CLI it will ask for input.
So if we test our network service with a telnet.
And we have our network service ready:
telnet localhost 60321 Trying ::1... Trying 127.0.0.1... Connected to localhost. Escape character is '^]'.
we type: “gonzalo” and:
gonzalo hello gonzalo Connection closed by foreign host.
Posted on May 23, 2010, in Linux, php, Technology. Bookmark the permalink. 12 Comments.
























Great article.
One question, if there was no CR coming in, just a fixed length 128 characters, some non printable, what would the php code look like?
You can handle it with standar PHP’s file manipulation funtions. fread instead of fgets will work if you know the lenght of the buffer.
Great stuff, I’ll try it and let you know. Thanks!
Excellent tutorial thanks!
I have a question: how I can know the IP of the remote client?
You can see the client IP with the same technique than with a http request: with $_SERVER['REMOTE_ADDR']. You also must take into account that remote IP can be behind a proxy have a look to: http://kcy.me/9unu
This is my code and the remote IP is always zero which is my mistake?
$IpX = $_SERVER['REMOTE_ADDR'];
$handle = fopen(‘php://stdin’,'r’);
$input = fgets($handle);
fclose($handle);
//Determinar longitud
if (strlen($input) > 10) {
//Base de DAtos
//$IpX = ’000.000.000.000′;
$hostname_localhost = “localhost”;
$database_localhost = “database”;
$username_localhost = “user”;
$password_localhost = “pass”;
$localhost = mysql_connect($hostname_localhost, $username_localhost, $password_localhost) or trigger_error(mysql_error(),E_USER_ERROR);
//CREAMOS EL QUERY PARA INGRESAR EL REGISTRO
$sqlQuery = “INSERT INTO hitser_gps.log (Ip,Log) VALUES (‘$IpX’,'$input’)”;
//INSERTAMOS EL REGISTRO
$table = mysql_query($sqlQuery, $localhost) or die(mysql_error());
};
thanks
I use:
$host = $_SERVER['REMOTE_HOST'] ? $_SERVER['REMOTE_HOST'] : $_SERVER['HOST'];In my local LAN
Funciona !!! Maestro !!!! For several days searching for an answer …
http://stackoverflow.com/questions/11462128/xinetd-obtain-remote-ip-with-php
Gracias
Then you owe me a beer.
True …. when you say friend!
Pingback: Webby Scripts Building network services with PHP and xinetd « Gonzalo Ayuso …
Pingback: Sending sockets from PostgreSQL triggers with Python « Gonzalo Ayuso | Web Architect