I have an HL7 machine that sends data via TCP on a specified port. I want to continuously listen on that port and display any data received on the screen.
I have this which creates a connection but in my scenario, connection is created by the HL7 machine which then starts sending.
// host and port to connect to
$host = "localhost";
$port = 9876;
// connect to the port
$fp = fsockopen($host, $port, $errno, $errstr);
set_time_limit(0);
// if connection not successfull, display error
if (!$fp)
{
die("Error: Could not open socket for connection!");
}
else
{
// connection successfull, listen for data (1024 bytes by default)
$got = fgets($fp);
// display the data
echo $got;
}
fclose($fp);
You should wait (block) for a socket connection from the HL7 machine. When a connection is received you should process the data then wait for another connection.
If several connections are made at once and your processing of the HL7 message takes a bit of time, it may be wise to process the message/data from the socket in a new thread.
<?php
$condition = true;
$socket = socket_create_listen(port);
socket_set_block($socket);
while (condition) {
socket_accept($socket);
// read data from socket
// condition to break from listening
}
?>
Reference: http://php.net/manual/en/function.socket-set-block.php
Related
I have a php socket server and a javascript websocket, but websocket stuck in connecting to socket.
There is no error but websocket stay connecting.
sock.php
set_time_limit(0);
$ip = '127.0.0.1';
$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
$ret = socket_bind($sock, $ip);
$ret = socket_listen($sock);
do
{
$ref = socket_accept($sock);
/*
Write message
*/
$msg ="Success receive from client\n";
socket_write($ref, $msg, strlen($msg));
/*
Read message
*/
$buf = socket_read($ref , 1024);
echo "Received message: $buf\n";
socket_close($ref);
}while (true);
socket_close($sock);
?>
javascript websocket:
var sock = new WebSocket('ws://localhost/sock.php');
sock.onopen(function()
{
console.log('socket connected.');
});
You must specify the correct port in socket_bind() or it will listen on a random port. You check this with netstat on Linux and Windows. As you try to connect to ws://localhost that should be port 80. However binding to port 80 is usually not allowed, unless you are an admin user. Best to bind to another port, for example 8080, and connect to ws://localhost:8080.
I am working on PHP socket programming project. In this project we are going to create a service in php socket. This socket will listen on one particular port. And client from outside network will able to communicate on that port.
Till now I am able to create server and client in php for socket programming. Now my pc is connected to LAN so I have to use port forward for connecting my pc with outside client. I forward port 2000 and all communication on that port is transfer to my pc IP address. I have netgear router n150 wireless adsl .I add all configuration on that router. I test port forwarding online at this site http://www.yougetsignal.com/tools/open-ports/ it says port is open.
I test my code on locally (intranet), it is working fine. But when I trying to run server on my pc and client from web server which is my ipage hosting server. It throws me error "Server Could not connect to server".
Server.php
<?php
// set some variables
// My LAN Ip
$host = "192.168.0.5";
$port = 2000;
// 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");
$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);
echo "Client Message : " . $input;
// reverse client input and send back
$output = strrev($input) . "\n";
socket_write($spawn, $output, strlen($output)) or die("Could not write output\n");
// close sockets
socket_close($spawn);
socket_close($socket);
?>
Client.php
<?php
//my public ip
$host = "117.223.90.191";
// port on which I port forword
$port = 2000;
$message = "Hello Server";
echo "Message To server :" . $message;
// create socket
$socket = socket_create(AF_INET, SOCK_STREAM, 0) or die("Could not create socket\n");
// connect to server
$result = socket_connect($socket, $host, $port) or die("Could not connect to server\n");
// send string to server
socket_write($socket, $message, strlen($message)) or die("Could not send data to server\n");
// get server response
$result = socket_read($socket, 1024) or die("Could not read server response\n");
echo "Reply From Server :" . $result;
// close socket
socket_close($socket);
?>
Any suggestion for problem. I think many will have same problem like me.
Even if i think the problem is in the lan forwarding, try testing it with :
telnet 117.223.90.191 2000
another thing to try is to make the server listen on all interfaces
$host = "0.0.0.0";
and take a look at http://reactphp.org/
Below is a PHP script that I have created to listen for incoming messages (XML strings).
That PHP script is hosted on my local home server on port 13330 so that's where I would listen for incoming requests, right? So I create the socket and bind it to the address the file is located on.
I receive this error: Warning: socket_bind(): unable to bind address [0]: Only one usage of each socket address (protocol/network address/port) is normally permitted.
I would appreciate it if anyone could let me know why I might be seeing that.
Thanks
createSocketServer();
function createSocketServer() {
// Set time limit to indefinite execution
set_time_limit (0);
// Set the ip and port we will listen on
$address = '127.0.0.1';
$port = 13330;
// Create a TCP Stream socket
$sock = socket_create(AF_INET, SOCK_STREAM, 0);
echo '<p>Socket created</p>';
// Bind the socket to an address/port
socket_bind($sock, $address, $port) or die('Could not bind to address');
echo '<p>Socket binded</p>';
// Start listening for connections
socket_listen($sock);
echo '<p>Socket listening</p>';
/* Accept incoming requests and handle them as child processes */
$client = socket_accept($sock);
// Read the input from the client – 1024 bytes
$input = socket_read($client, 1024);
// Strip all white spaces from input
$output = ereg_replace("[ \t\n\r]","",$input).chr(0);
echo $output;
}
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
I am trying to connect to a server socket which will send me a bunch of data after connecting, take a response from me, and then send a bunch more data, repeating this process until it determines its had enough.
So basically, after first~ connecting, we will (and currently are) receiving data from the server. We want to take this data, compute it in another script/program passing with AJAX, and then return to this and respond to the server.
We're afraid that once we take data from the server, go to compute the data, the socket is going to close and we're not going to be able to continue where we left off.
How can we make sure that php persists in its connection to this socket? I've looked into fsockopen and I'm not quite understanding of it and whether it will help here or not. Any assistance?
// create socket
//$socket = socket_create(AF_INET, SOCK_STREAM, 0) or die("Could not create socket\n");
$socket = fsockopen($host, $port, $errno, $errstr, 30);
if (!$socket) {
echo "$errstr ($errno)<br />\n";
}
$_SESSION['socket'] = $socket;
// receive DATA from server
//$result = socket_connect($socket, $host, $port) or die("Could not connect to server\n");
echo "Connected to server";
//$_SESSION['connection'] = $result;\
//STOP, PASS DATA, COMPUTE, SEND RESPONSE
// send response to server
fwrite($socket, $message1) or die("Could not send data to server\n");
// get data server response
$result = fread ($socket, 1024) or die("Could not read server response\n");
echo "<br>Reply From Server :".$result;
// close socket
fclose($socket);
I created a PHP Socket Server with PHP_NORMAL_READ mode. So, a message to the server is read when it ends with \n or \r. I tried it by connecting to the server with multiple telnet instances, and it works great.
However, when I connect to the server with 1 flash application and 1 telnet application (I first start the flash one), the flash one seems to make the server hang - the server is getting stuck somewhere and no longer receiving data from eg. the telnet client.
Because anyone can code a flash client, this has to be fixed server side. The server's code:
<?php
// config
$timelimit = 60; // amount of seconds the server should run for, 0 = run indefintely
$port = 9000; // the port to listen on
$address = $_SERVER['SERVER_ADDR']; // the server's external IP
$backlog = SOMAXCONN; // the maximum of backlog incoming connections that will be queued for processing
// configure custom PHP settings
error_reporting(1); // report all errors
ini_set('display_errors', 1); // display all errors
set_time_limit($timelimit); // timeout after x seconds
ob_implicit_flush(); // results in a flush operation after every output call
//create master IPv4 based TCP socket
if (!($master = socket_create(AF_INET, SOCK_STREAM, SOL_TCP))) die("Could not create master socket, error: ".socket_strerror(socket_last_error()));
// set socket options (local addresses can be reused)
if (!socket_set_option($master, SOL_SOCKET, SO_REUSEADDR, 1)) die("Could not set socket options, error: ".socket_strerror(socket_last_error()));
// bind to socket server
if (!socket_bind($master, $address, $port)) die("Could not bind to socket server, error: ".socket_strerror(socket_last_error()));
// start listening
if (!socket_listen($master, $backlog)) die("Could not start listening to socket, error: ".socket_strerror(socket_last_error()));
//display startup information
echo "[".date('Y-m-d H:i:s')."] SERVER CREATED (MAXCONN: ".SOMAXCONN.").\n"; //max connections is a kernel variable and can be adjusted with sysctl
echo "[".date('Y-m-d H:i:s')."] Listening on ".$address.":".$port.".\n";
$time = time(); //set startup timestamp
// init read sockets array
$read_sockets = array($master);
// continuously handle incoming socket messages, or close if time limit has been reached
while ((!$timelimit) or (time() - $time < $timelimit)) {
$changed_sockets = $read_sockets;
socket_select($changed_sockets, $write = null, $except = null, null);
foreach($changed_sockets as $socket) {
if ($socket == $master) {
if (($client = socket_accept($master)) < 0) {
continue;
} else {
array_push($read_sockets, $client);
}
} else {
$data = #socket_read($socket, 1024, PHP_NORMAL_READ); //read a maximum of 1024 bytes until a new line has been sent
if ($data === false) { //the client disconnected
$index = array_search($socket, $read_sockets);
unset($read_sockets[$index]);
socket_close($socket);
} elseif ($data = trim($data)) { //remove whitespace and continue only if the message is not empty
echo "we received: ".$data."\n\n";
//handleData($data, $socket);
}
}
}
}
socket_close($master); //close the socket
echo "[".date('Y-m-d H:i:s')."] SERVER CLOSED.\n";
//function to write to the flash client
function flash_write($socket, $msg) {
socket_write($socket, $msg.chr(0x0));
}
?>
Does anyone know what may cause this? I tried changing the timeout on the socket_select from none to 0 (instant return), but that didn't seem to change anything.
Could you post the source of the flash client? That would show what the problem is?
Are you sure the last thing you send from the flash client is a \n ?
Otherwise the server would block on socket_read() as the flash client socket can be read without blocking (triggered socket_select()), but doesn't send the ending \n.
One thing to help you debug: error_reporting(1) does not enable the display of all errors. Look at the documentation at http://us3.php.net/manual/en/function.error-reporting.php. You need something like error_reporting(E_ALL).