I have socket client which connects to server and which wait for datas to be sent by this server.
It works fine but, when server has a disconnection, it has to be detected by socket client in order to try a reconnection.
Client socket code :
$co = false;
while (!$co) {
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($socket === false) {
echo "socket_create()error : " . socket_strerror(socket_last_error()) . "\n";
} else {
echo "OK 1.\n";
}
echo "Try connection '$address' on port '$service_port'... \n";
$result = socket_connect($socket, $address, $service_port);
if ($socket === false) {
echo "socket_connect() error : ($result) " . socket_strerror(socket_last_error($socket)) . "\n";
} else {
socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, array("sec" => 1, "usec" => 0));
echo "OK 2.\n";
$co = true;
}
}
while (true) {
echo 'read' . PHP_EOL;
socket_clear_error($socket);
$out = socket_read($socket, 2048);
$socket_last_error = socket_last_error($socket);
$strErr = socket_strerror($socket_last_error) . ' ' . $socket_last_error;
echo("socket_last_error : " . $strErr);
var_dump($out);
}
Problem is when client socket is correctly connected to server, there's socket_last_error with value 'Resource temporarily unavailable 11' and 'socket_read' function return false when server doesn't send data.
But when server is deconnected, there's socket_last_error with value 'Success 0' and 'read' function return ''
PHP doc says :
socket_read() returns data as string on success, or FALSE on error (including case where remote host has closed connection).
So functions results are unexpected and I would like to know what's the right method to detect a server disconnection in order to try a new connection?
Thanks in advance for your answers.
Related
I just want to establish connection with FIX api using host and port (which i gave by puchasing connection) and if i connect successfuly then i send a logon request to login on FIX api and then i rececived server response but the problem is i receive a empty(0) respose
MY CODE IS
<?php
/*
Template Name: connection
*/
?>
<?php
error_reporting(E_ALL);
date_default_timezone_set('Asia/Kolkata');
echo date("YmdH:i:s.ms");
$date =date("Ymd-H:i:s.ms");
/* Get the port . */
$service_port = "(some port no.)";
/* Get the IP address for the target host. */
$address = gethostbyname('.....some host name....');
/* Create a TCP/IP socket. */
$socket = socket_create(AF_INET, SOCK_STREAM, 0);
if ($socket === false) {
echo "socket_create() failed: reason: " . socket_strerror(socket_last_error()) . "\n";
} else {
echo "OK.............<br>";
}
echo "................Attempting to connect to '$address' on port '$service_port'......<br>";
$result = socket_connect($socket, $address, $service_port);
if ($result === false) {
echo "socket_connect() failed.\nReason: ($result) " . socket_strerror(socket_last_error($socket)) . "\n";
} else {
echo "OK............,<br>";
}
$in = "8=FIX.4.3\0019=149\00135=A\00134=1\00149="SenderCompID"\00152=".$date."\00156="TargetCompID"\00198=0\001108=60\001141=Y\001553="Username"\001554="Password"\00110=161\001";
$out = '';
echo "Sending request...";
socket_write($socket, $in, strlen($in));
echo "OK...........<br>";
echo "<br> ------------------Reading response:-------------------<br>";
$buf = 'This is my buffer.';
if (false !== ($bytes = socket_recv($socket, $buf, 2048, MSG_WAITALL))) {
echo "Read $bytes bytes from socket_recv(). Closing socket...<br>";
} else {
echo "socket_recv() failed; reason: " . socket_strerror(socket_last_error($socket)) . "\n";
}
socket_close($socket);
echo $buf . "Message End <br>";
echo "OK.\n\n";
?>
The output I am getting in my XAMPP server page in Wordpress is:
2020031910:11:35.0335OK.............
................Attempting to connect to '(some Host IP Adress)' on port '(port no)'......
OK............,
Sending request...OK...........
------------------Reading response:-------------------
Read 0 bytes from socket_recv(). Closing socket...
Message End
OK.
I would like to ask some things:
1) Is this occuring because of my code or configuration ?
2) Or is this because of issue at FIX server ?
3) Is there any other method to connect with FIX server?
It could be you need to change the line
if (false !== ($bytes = socket_recv($socket, $buf, 2048, MSG_WAITALL))) {
echo "Read $bytes bytes from socket_recv(). Closing socket...<br>";
} else {
echo "socket_recv() failed; reason: " . socket_strerror(socket_last_error($socket)) . "\n";
}
Why don’t you try using https://www.quickfixj.org/ it is industry standard.
I am working on Client Server Socket Program for chat like application, but it is giving following error message
Warning: socket_bind(): unable to bind address [98]: Address already in use.... Could not bind to address on line 15
I have seen various tutorials, but i want Server to listen to client request continuously. I have seen port number it is open also but still the same message. I am stuck at this point for several days could not get proper solutions. Please help to solve it thanks.....
Server.php:
<?php
error_reporting(E_ALL);
/* Allow the script to hang around waiting for connections. */
set_time_limit(0);
/* Turn on implicit output flushing so we see what we're getting
* as it comes in. */
ob_implicit_flush();
$address = 'XXX.XX.XX.XXX';
$port = 15213;
if (($sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) === false) {
echo "socket_create() failed: reason: " . socket_strerror(socket_last_error()) . "\n";
}
if (socket_bind($sock, $address, $port) === false) {
echo "socket_bind() failed: reason: " . socket_strerror(socket_last_error($sock)) . "\n";
}
if (socket_listen($sock, 5) === false) {
echo "socket_listen() failed: reason: " . socket_strerror(socket_last_error($sock)) . "\n";
}
do {
if (($msgsock = socket_accept($sock)) === false) {
echo "socket_accept() failed: reason: " . socket_strerror(socket_last_error($sock)) . "\n";
break;
}
/* Send instructions. */
$msg = "\nWelcome to the PHP Test Server. \n" .
"To quit, type 'quit'. To shut down the server type 'shutdown'.\n";
socket_write($msgsock, $msg, strlen($msg));
do {
if (false === ($buf = socket_read($msgsock, 2048, PHP_NORMAL_READ))) {
echo "socket_read() failed: reason: " . socket_strerror(socket_last_error($msgsock)) . "\n";
break 2;
}
if (!$buf = trim($buf)) {
continue;
}
if ($buf == 'quit') {
break;
}
if ($buf == 'shutdown') {
socket_close($msgsock);
break 2;
}
$talkback = "PHP: You said '$buf'.\n";
socket_write($msgsock, $talkback, strlen($talkback));
echo "$buf\n";
} while (true);
socket_close($msgsock);
} while (true);
socket_close($sock);
?>
Client.php
<?php
error_reporting(E_ALL);
echo "<h2>TCP/IP Connection</h2>\n";
/* Get the port for the WWW service. */
$service_port = getservbyname('www', 'tcp');
/* Get the IP address for the target host. */
$address = gethostbyname('www.example.com');
/* Create a TCP/IP socket. */
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($socket === false) {
echo "socket_create() failed: reason: " . socket_strerror(socket_last_error()) . "\n";
} else {
echo "OK.\n";
}
echo "Attempting to connect to '$address' on port '$service_port'...";
$result = socket_connect($socket, $address, $service_port);
if ($result === false) {
echo "socket_connect() failed.\nReason: ($result) " . socket_strerror(socket_last_error($socket)) . "\n";
} else {
echo "OK.\n";
}
$in = "HEAD / HTTP/1.1\r\n";
$in .= "Host: www.example.com\r\n";
$in .= "Connection: Close\r\n\r\n";
$out = '';
echo "Sending HTTP HEAD request...";
socket_write($socket, $in, strlen($in));
echo "OK.\n";
echo "Reading response:\n\n";
while ($out = socket_read($socket, 2048)) {
echo $out;
}
echo "Closing socket...";
socket_close($socket);
echo "OK.\n\n";
?>
In both php files you create a Socket on the same port. That is the problem.
The Server has to create the Socket while the client has to use the Socket (not creating it, too)
Two applications can not create the same socket and listen on the same port.
EDIT:
I have tested your script with xampp at localhost. so IP was 127.0.0.1. The Server listened properly on port 15213 and the client connected properly on this port.
That the port was open i saw with the xampp controll panel.
If you use your scripts like you posted here, then you have to replace in Server.php
$address = 'XXX.XX.XX.XXX';
with
$address = '127.0.0.1';
and in Client.php
$address = gethostbyname('www.example.com');
with
$address = gethostbyname('localhost');
or
$address = '127.0.0.1';
I want to do something like this article:
broadcast to detect Server IP address
and transfer to PHP, does it possible?
The reason is I want to send broadcast socket to server, and the server will return message then I can determine the message is what I want or not to detect the true IP of the message sender.
The code is like:
<?php
error_reporting(E_ALL);
$address = "255.255.255.255";
$port = 10000;
/* Create a udp socket. */
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($socket === false) {
echo "socket_create() failed: reason: " . socket_strerror(socket_last_error()) . "<br/>";
} else {
echo "socket successfully created.<br/>";
}
echo "Attempting to connect to '$address' on port '$port'..."."<br/>";
$result = socket_connect($socket, $address, $port);
if ($result === false) {
echo "socket_connect() failed.\nReason: ($result) " . socket_strerror(socket_last_error($socket)) . "<br/>";
} else {
echo "successfully connected to $address."."<br/>";
}
$i="theMessage";
echo "Sending $i to server."."<br/>";
socket_write($socket, $i, strlen($i));
$input = socket_read($socket, 512);
echo "Response from server is: $input"."<br/>";
$ip="";
if($input=="I want")
$ip=socket_send_from_the_IP; // just psuedocode
echo "Closing socket...";
socket_close($socket);
?>
Or is the direction of my question wrong?
I also think that I should use httprequest?
Any answer appreciated.
Hi there's problem with the socket_read function below, it does not return empty string '' after it has finished reading the data. On second call to socket_read() it just hang there, the page keep loading in browser with no return.
It works if the server close the connection, is it a must for server to close the client socket ? Thanks
$json = $_GET['json'];
/* Get the port for the WWW service. */
// $service_port = getservbyname('www', 'tcp');
$service_port = "1111";
/* Get the IP address for the target host. */
$address = "192.168.3.5";
/* Create a TCP/IP socket. */
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($socket === false) {
echo "socket_create() failed: reason: " . socket_strerror(socket_last_error()) . "\n";
die();
} else {
//echo "OK.\n";
}
//echo "Attempting to connect to '$address' on port '$service_port'...";
$result = socket_connect($socket, $address, $service_port);
if ($result === false) {
echo "socket_connect() failed.\nReason: ($result) " . socket_strerror(socket_last_error($socket)) . "\n";
die();
} else {
//echo "OK.\n";
}
$out = '';
//echo "Sending HTTP HEAD request...";
$result = socket_write($socket, $json, strlen($json));
if ($result === false) {
echo "socket_connect() failed.\nReason: ($result) " . socket_strerror(socket_last_error($socket)) . "\n";
die();
} else {
//echo "OK.\n";
}
echo socket_read($socket, 2048);
echo socket_read($socket, 2048);
//
// while (socket_read($socket, 2048) !== '') {
// echo $out;
//
// }
//
socket_close($socket);
Yes, that's exactly what I'd expect it to do - socket_read() will never return an empty string unless you open it a binary and the server responds with '\0'.
You seem to be trying to write an HTTP client. If you are, STOP NOW, throw away your code and go read up on the Curl extension. HTTP is not a simple protocol, and you've still got a lot to learn about how the simple stuff works. You are curently relying on the socket state and the format of the data to determine the data flow - but HTTP uses neither.
If you want to learn how HTTP works, then there's lots of documentation on the internet - the RFC's are a must, but are not a gentle introduction. If your objective is to develop an application, then use curl (or even the HTTP stream wrappers).
Here is my code
<?php
error_reporting(E_ALL);
/* Allow the script to hang around waiting for connections. */
set_time_limit(0);
/* Turn on implicit output flushing so we see what we're getting
* as it comes in. */
ob_implicit_flush();
$address = 'localhost';
$port = 10000;
if (($sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) === false) {
echo "socket_create() failed: reason: " . socket_strerror(socket_last_error()) . "\n";
}
if (socket_bind($sock, $address, $port) === false) {
echo "socket_bind() failed: reason: " . socket_strerror(socket_last_error($sock)) . "\n";
}
if (socket_listen($sock, 5) === false) {
echo "socket_listen() failed: reason: " . socket_strerror(socket_last_error($sock)) . "\n";
}
do {
if (($msgsock = socket_accept($sock)) === false) {
echo "socket_accept() failed: reason: " . socket_strerror(socket_last_error($sock)) . "\n";
break;
}
do {
$out = socket_read($msgsock, 2048);
if (!empty($out)) {
if ($out == 'quit') {
break;
}
elseif ($out == 'shutdown') {
socket_write($msgsock, 'plc down', 8);
socket_close($msgsock);
break 2;
}
else {
switch ($out) {
case "KABBE": $response = "Kabbe te!"; break;
case "SZOPJ": $response = "Szopjal te!"; break;
default: $response = "Ismeretlen parancs";
}
socket_write($msgsock, $response, strlen($response));
break;
}
}
} while (true);
socket_close($msgsock);
} while (true);
socket_close($sock);
?>
and now the errors
Warning: socket_bind() [function.socket-bind]: unable to bind address [0]: Only one usage of each socket address (protocol/network address/port) is normally permitted. in C:\wamp\www\socket\socket.php on line 18
socket_bind() failed: reason: Only one usage of each socket address (protocol/network address/port) is normally permitted.
Warning: socket_listen() [function.socket-listen]: unable to listen on socket [0]: An invalid argument was supplied. in C:\wamp\www\socket\socket.php on line 22
socket_listen() failed: reason: An invalid argument was supplied.
Warning: socket_accept() [function.socket-accept]: unable to accept incoming connection [0]: An invalid argument was supplied. in C:\wamp\www\socket\socket.php on line 27
socket_accept() failed: reason: An invalid argument was supplied.
I searched on google but nothing useful.
What is the problem?
PHP also offers stream_socket_server and other stream_socket_* functions.
I found these to be more developer friendly.
Example code from php.net:
$socket = stream_socket_server("tcp://localhost:8000", $errno, $errstr);
if (!$socket) {
echo "$errstr ($errno)<br />\n";
} else {
while ($conn = stream_socket_accept($socket)) {
fwrite($conn, 'The local time is ' . date('n/j/Y g:i a') . "\n");
fclose($conn);
}
fclose($socket);
}
'localhost' isn't a valid address as socket_bind doesn't accept DNS names, use the equivalent IP address '127.0.0.1'.
More info
That means you already have an open socket on your computer on that port.
Try switching to another unused port.
On Windows (which is what you seem to be working on), you can see the list of open sockets from the command line:
netstat -an
If you want to know which processes are listening to those ports, try this instead:
netstat -ban
use this code before binding:
if (!socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1)) {
echo socket_strerror(socket_last_error($socket));
exit;
}
for reference http://www.php.net/manual/en/function.socket-bind.php
You can also check http://www.php.net/manual/en/function.socket-set-option.php for details