PHP socket server answer eof char to linux telnet - php

I want to talk with php server with socket by telnet.
I wrote 'echo' server (i send string to server, server send it to me)
i use chr(0) on end of output string to send information that string is sent
socket_write($client, $output.chr(0));
but telnet haven't see it and i cant send new string
TELNET
telnet 127.0.0.1 9000
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
hello
hello_
PHP
<?php
set_time_limit (0);
$address = '127.0.0.1';
$port = 9000;
$sock = socket_create(AF_INET, SOCK_STREAM, 0);
socket_bind($sock, $address, $port) or die('Could not bind');
socket_listen($sock);
while(true) {
$client = socket_accept($sock);
$input = trim(socket_read($client, 1024));
if ($input == 'off') break;
$output = $input.chr(0);
socket_write($client, $output);
}
socket_close($client);
socket_close($sock);
?>
what i'm doing wrong?

You should end the lines with carriage return or "\r\n", instead of just the \0 character. The telnet client watches out for them too I think.
The real problem however is your use of $client = socket_accept(..) within the loop. You must only establish the connection once, before the while. Otherwise you will reset the connected stream.

Related

PHP udp server: unable to connect to remote host

I get this error message, when try connect to tiny UDP server. The source code is minimized and looks like so:
//server.php
$server_host = '127.0.0.1';
$server_port = 21665;
$poll_interval = 0.5;
$socket = socket_create(AF_INET, SOCK_DGRAM, 0);
socket_bind($socket, $server_host, $server_port);
$clients = [$socket];
while(true) {
$read = $clients;
$write = [];
$except = [];
if (socket_select($read, $write, $except, $poll_interval) < 1){
continue;
}
if (in_array($socket, $read)) {
echo "Client submitted request!\n";
//request parsing
}
}
So, when I run the server with $ php server.php it hangs for ever, as it should. When however I try to connect to it through telnet to post a request I get an error message:
$ telnet 127.0.0.1 21665
Trying 127.0.0.1 ...
Telnet: unable to connect to remote host: Connection refused
What I'm doing wrong and how can I fix it?
What I'm doing wrong
You are using telnet (a TCP client) to try to connect to a UDP port.
how can I fix it
Use a client that supports UDP, for example netcat as explained in this answer: telnet counterpart for udp
nc -u <host> <port>
Start typing and press enter.

make the server wait the [FIN + ACK] from the client before closing the socket

I have the following php script (tcp server)
<?php
$sock = socket_create(AF_INET, SOCK_STREAM, 0);
// Bind the socket to an address/port
socket_bind($sock, "0.0.0.0", 14010) or die('Could not bind to address');
$i=0;
for(;;) {
// Start listening for connections
socket_listen($sock);
/* Accept incoming requests and handle them as child processes */
$client = socket_accept($sock);
// Read the input from the client – 1024 bytes
$in = socket_read($client, 41984);
socket_write($client, $in);
//socket_close($client);
}
// Close the master sockets
socket_close($sock);
?>
How I can make the server wait the [FIN + ACK] from the client before closing the socket?
You can instead of calling close, do a recv on socket (not sure of php construct). recv system call returns 0 on peer closure. If this is the case you can then close on server side.

get UDP Multicast stream in PHP

I am trying to receive a UDP multicast stream in PHP. The receive command never gets anything and waits forever.
I can watch the stream using VLC player so the stream is accessible on my machine. Any help on how to do this using PHP is highly appreciated.
Here is my code.
<?php
error_reporting(E_ALL | E_STRICT);
//create a new socket
$socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
//i am not sure about this command. I think i have to set this option to start receiving packets.
socket_set_option($socket, SOL_SOCKET, MCAST_JOIN_SOURCE_GROUP, array("group"=>"239.194.0.73","interface"=>"eth0","source"=>"239.194.0.73"));
$binded = socket_bind($socket, '127.0.0.1', 6073);
//receive data
$from = '';
$port = 0;
socket_recvfrom($socket, $buf, 12, MSG_WAITALL, $from, $port);
echo "Received $buf from remote address $from and remote port $port" . PHP_EOL;
?>
$binded = socket_bind($socket, '127.0.0.1', 6073);
Should be
$binded = socket_bind($socket, '0.0.0.0', 6073);
Or else you will only recv packets originating from the local host.

How to read php socket connection response?

Following is my socket connection request and response order.
$socket = socket_create(AF_INET, SOCK_STREAM, 0);
$connection = socket_connect($socket, $Host, $Port);
$Md5CheckSum = md5($msg);
$WillWait = 'SOAP '. $Md5CheckSum. ' WILL_WAIT'."\n";
socket_write($socket,$WillWait);
socket_write($socket,$msg);
socket_write($socket, SoapSender::$TERM_CHAR);
sleep(1);
$buf = socket_read($socket, 2048);
//socket_write($socket,"&\r\n");
echo "$buf\n";
Please could somebody tell me how to read response that I receive after last socket_write request. I have been searching for this answer all day but have not been able to find any help through Google.
Thanks a lot for your time.
Two functions should be used:
stream_set_blocking($socket, true);
And
stream_get_contents($socket);
Setting a block on your stream requires the return of data before your application will continue execution of the script.
If you do not set a stream block, sometimes latency will cause your PHP script to think there was no response, causing you to not receive data.
Also, use stream_get_contents to pull from the socket. This will grab by default the full buffer.
The correct way is to use socket_read, not stream_get_contests as someone else suggested.
Here is an example:
$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
$result = socket_connect($sock, "10.197.24.40", "5000");
$request = '{ "request" : { "id" : "some_function_id", "data": "55555555-5"} }';
// We send the request
socket_write($sock,$request);
socket_read($sock,1000000);
socket_close($sock);
I have tested this code in a live environment and it works correctly.

Is there a way to specify the source UDP port using PHP?

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>

Categories