I'm trying to set up a socket server in php that stays open. This example taken from php.net will close after it receives connection...even after I comment out socket_close($spawn)
<?
// set some variables
$host = "192.168.1.109";
$port = 1234;
// don't timeout!
set_time_limit(0);
// create socket
$socket = socket_create(AF_INET, SOCK_STREAM, 0) or die("Could not create
socket\n");
// bind socket to port
$result = socket_bind($socket, $host, $port) or die("Could not bind to
socket\n");
// start listening for connections
$result = socket_listen($socket, 3) or die("Could not set up socket
listener\n");
// accept incoming connections
// spawn another socket to handle communication
$spawn = socket_accept($socket) or die("Could not accept incoming
connection\n");
// read client input
$input = socket_read($spawn, 1024) or die("Could not read input\n");
// clean up input string
$input = trim($input);
// reverse client input and send back
//$output = $input . "\n";
$output = strrev($input) . "\n";
echo $input;
socket_write($spawn, $output, strlen ($output)) or die("Could not write
output\n");
// close sockets
//socket_close($spawn);
//socket_close($socket);
?>
and here is the code for the client connecting...
<?php
$fp = fsockopen("192.168.1.109", 1234, $errno, $errstr, 30);
if (!$fp) {
echo "$errstr ($errno)<br />\n";
} else {
//$out = "testing";
$out = "GET / HTTP/1.1\r\n";
$out .= "Host: 127.0.0.1\r\n";
$out .= "Connection: Close\r\n\r\n";
$out .= "testing\n";
fwrite($fp, $out);
while (!feof($fp)) {
echo fgets($fp, 128);
}
fclose($fp);
//exit();
}
//exit;
?>
socket_read without the O_NONBLOCK flag (see socket_set_nonblock) is a blocking operation, so it will wait there until it receives something.
As soon as something is received, the rest of the script continues, and exits, as there is no loop in place to do the next read. (i.e: in a server it's usual to do a while(true){} loop)
You need to wrap the accept in a loop or something. It closes because the script execution has ended.
You could do something like this:
while ($spawn = socket_accept($socket)) {
//do stuff
}
Related
I have a netcat server, running from command line:
netcat -l -q0 -p 9999 -c "tesseract stdin stdout -l spa"
I can connect to this server using netcat client:
cat /tmp/autogenerado.jpg | netcat 127.0.0.1 9999
So, I send a jpeg file to another server, and receive the OCR'ed data in client.
I want to do this in PHP:
$fp = fsockopen("tcp://127.0.0.1:9999", $errno, $errstr);
if (!$fp) {
echo "{$errno}: {$errstr}\n";
die();
}
fwrite($fp, $jpeg);
$contents = stream_get_contents($fp);
fclose($fp);
return $contents;
But the script hangs on stream_get_contents. I think it is because the netcat server doesn't know when the PHP client has finished sending data.
Is it possible to send an EOF ?
You need to shutdown the socket for writing, something like this:
<?php
$stream = stream_socket_client("tcp://whatever:9999", $errno, $errstr);
if (!$stream) {
echo "{$errno}: {$errstr}\n";
die();
}
fwrite($stream, $jpeg);
stream_socket_shutdown($stream, STREAM_SHUT_WR); /* This is the important line */
$contents = stream_get_contents($stream);
fclose($stream);
return $contents;
?>
For reference, final working code is:
$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
$result = socket_connect($sock, "10.187.252.35", 9999);
socket_send($sock,$bdata,strlen($bdata),MSG_EOR):
socket_shutdown ($sock,1);
while ($out = socket_read($sock, 2048)) {
echo $out;
}
socket_close($sock);
I'm working on a Server list viewer
and somebody told me that i should use UdpSocket to send data to the master server and receive data from it (in this case for MW2-IW4 game)
So this is the command or the socket you use
"\xff\xff\xff\getservers IW4 <MASTERSERVERPORTHERE> full empty\x00"
so i tried to work with this code
<?php
$sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
$msg = "\xff\xff\xff\getservers IW4 <MASTERSERVERPORT> full empty\x00";
$len = strlen($msg);
socket_sendto($sock, $msg, $len, 0, 'MASTERSERVERIP' , 1223);
socket_close($sock);
?>
but didn't receive any data , just getting the number 36 ...
PS:
i don't know much things about sockets.
i figured out how to do it a while ago and remembered this post, if anybody is still interested, this is how you do it:
<?php
$ip = "127.0.0.1";
$port = 1337;
$socket = fsockopen('udp://'.$ip, $port);
stream_set_blocking($socket, 0);
stream_set_timeout($socket, 1); //1 = timeout
fwrite($socket, "YOUR UDP COMMAND HERE\n");
$time=time()+1; //1=timeout
$returned = "";
while($time > time()) {
$returned .= fgets($socket);
}
echo($returned); // the returned value
#fclose($socket); //we are done, so better close it.
?>
Just use fsockopen it's a lot easier,
$fp = fsockopen("udp://127.0.0.1", 13, $errno, $errstr);
if (!$fp) echo "ERROR: $errno - $errstr<br />\n";
fwrite($fp, "\n");
while (!feof($fp)) {
echo fgets($fp, 128);
}
fclose($fp);
<?php
error_reporting(E_ALL);
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($socket === false)
echo "socket_create() failed: reason: " . socket_strerror(socket_last_error()) . "\n";
$result = socket_connect($socket, "92.51.77.126", 1080); // socks ip
if ($result === false)
echo "socket_connect() failed.\nReason: ($result) " . socket_strerror(socket_last_error($socket)) . "\n";
$in = "\x04\x02";
$in .= "\x00\x50"; // http proxy port
$in .= "\xc0\xf0\x2e\x7e"; // http proxy ip address
$in .= "\x00";
socket_write($socket, $in, strlen($in));
sleep(1);
$in = "HEAD / HTTP/1.1\r\n";
$in .= "Host: www.example.com\r\n";
$in .= "Connection: Close\r\n\r\n";
socket_write($socket, $in, strlen($in));
$out = '';
while ($out = socket_read($socket, 2048)) {
echo $out;
}
socket_close($socket);
?>
I'd like to bind a socks 4 proxy server to connect an another proxy. This example the secound proxy is a http proxy. When connect the first is normally connected the server answer is Granted, but the communication at this time is finished. How continued the communication this example?
You are lucky that you get a 'Granted' reply - I do not get any reply from SOCKS server in OpenSSH, it just closes the connection...
As I understand the SOCKS4 description, the answer for type 2 (BIND) request contains a port number and an IP address; when a connection arrives to them, your program will be able to read next status packet, which tells about the connection. There is a limited time (seems 2 minutes) of waiting for the connection. This is mainly for an FTP client - an FTP server needs back connection to the client and the BIND allows the connection to be passed.
If you want to initiate a connection from your side, use type 1 (CONNECT) request. Also, make sure the port and the IP address in the request are correct - seems in your code they are 80 and 192.240.30.126.
Im opening up a connection to a server that accepts XML requests. I am required to send two requests one after the other.
If I run the first request on its own I get data back
If I run the second request on its own I get data back
If I run both within a loop using the same connection, only the first request works, the second returns no data.
Is there something I need to send to the socket between each request to indecate the end of each request, otherwise what am I doing wrong?
// Open socket connection
$socket = pfsockopen($this->config['ip'], $this->config['port'], $errno, $errstr, 30);
// Try and open a connection
if ( ! $socket) {
throw new \Exception($errstr . '('.$errno.')');
}
// If connection was successfull start sending requests
else{
// Loop each request within the container
foreach($this->container as $key => $object){
print "Request" . ($key+1) . PHP_EOL;
// Reset data and post string
$data = array();
$xml_post_string = null;
// Create XML string
$xml = \LSS\Array2XML::createXML('request', $object->request);
$xml_post_string = $xml->saveXML();
// Add ending lines
$xml_post_string = $xml_post_string . PHP_EOL . PHP_EOL;
// Loop
fwrite($socket, $xml_post_string);
while ( ! feof($socket)) {
$data[] = fgets($socket, 1024);
}
// Tried adding, but fails
ftruncate($socket, 2);
if(count($data)){
print implode($data);
}
else{
print "No response from server - you broke it" . PHP_EOL;
}
}
}
fclose($socket);
A second attempt. The results are the same for any random server out there.
// Create a TCP/IP socket
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
// Connect the socket
socket_connect($socket, 'xxx.xxx.xxx.xxx', '80');
$xml_post_string_one = '<request><message>Hello first world</message></request>';
$xml_post_string_two = '<request><message>Hello second world</message></request>';
// FIRST ROUND //
// Send data to it
socket_write($socket, $xml_post_string_one, strlen($xml_post_string_one));
// Get data from it
socket_recv($socket, $bufA, 2048, MSG_WAITALL);
// Done
print strlen($bufA) . PHP_EOL; // Got info back
// SECOND ROUND //
// Send data to it
socket_write($socket, $xml_post_string_two, strlen($xml_post_string_two));
// Get data from it
socket_recv($socket, $bufB, 2048, MSG_WAITALL);
// Done
print strlen($bufB). PHP_EOL; // Returns 0, Why?
I need to send a message via UDP to a remote equipment. I know that if I use the same UDP port that it used while sending information to the server to write back to it the messages goes through.
I am currently using:
$fp = fsockopen( $destination, $port, $errno, $errstr);
if (!$fp) {
echo "ERROR: $errno - $errstr\n";
} else {
fwrite($fp, $m);
fclose($fp);
}
But in this way I have no control of which port is going to be used as the source port.
In Java have one can use:
client = new DatagramSocket(21000);
Is there a way to do something similar using PHP.
You could do it by creating a normal udp socket with socket_create() and using socket_bind() to bind it to a specific port. Then use e.g. socket_sendto for specifying the endpoint and port to send it to. Example code follows.
A simple server that spits out the port number and ip address of client using socket_stream_server():
<?php
set_time_limit (20);
$socket = stream_socket_server("udp://127.0.0.1:50000",
$errno, $errstr,
STREAM_SERVER_BIND);
if (!$socket) {
die("$errstr ($errno)");
}
do {
$packet = stream_socket_recvfrom($socket, 1, 0, $peer);
echo "$peer\n";
stream_socket_sendto($socket, date("D M j H:i:s Y\r\n"), 0, $peer);
} while ($packet !== false);
?>
and the client is like this:
<?php
$address = '127.0.0.1';
$port = 50001;
$dest_address = '127.0.0.1';
$dest_port = 50000;
$sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
if (socket_bind($sock, $address, $port) === false) {
echo "socket_bind() failed:" . socket_strerror(socket_last_error($sock)) . "\n";
}
$msg = "Ping !";
socket_sendto($sock, $msg, strlen($msg), 0, $dest_address, $dest_port);
socket_close($sock);
?>
Running the server (on the command line) gives this output when running the client multiple times:
<knuthaug#spider php>php server.php
127.0.0.1:50001
127.0.0.1:50001
127.0.0.1:50001
^C
<knuthaug#spider php>