I tried to write a PHP project to communicate with a PLC, but I have a problem when I close a socket client, it didn't close immediately, connected devices increase when I call an AJAX function to reload values, can anyone help me? I use RS_sim to simulate PLC
my page
My code to create and close socket client:
private function connect(){
// Create a protocol specific socket
if ($this->socket_protocol == "TCP"){
// TCP socket
$this->sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
}
$result = #socket_connect($this->sock, $this->host, $this->port);
if ($result === false) {
throw new Exception("socket_connect() failed.</br>Reason: ($result)".
socket_strerror(socket_last_error($this->sock)));
} else {
$this->status .= "Connected\n";
return true;
}}
private function disconnect(){
socket_close($this->sock);
$this->status .= "Disconnected\n";}
Related
I am making a PHP socket server but am unable to make my server read the socket.
$this->log("Creating socket (please wait)...");
$this->socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if(socket_bind($this->socket, "127.0.0.1", 8080) === false){
$this->log("Failed to bind socket to port (8080)");
exit();
}
socket_listen($this->socket, 5);
if(!is_resource($this->socket)){
$this->log("Socket isn't a resource. Something went wrong, exiting.");
exit();
}
$this->log("Socket created, creating socket reader...");
$this->socketReader = new SocketReader($this);
$this->log("server started");
//socket should be non-blocking
socket_set_nonblock($this->getSocket());
//called every 10000 microseconds to read socket (error line here)
public function process(){
$buffer = socket_read($this->getSocket(), 128);
var_dump($buffer);,
}
The error I get is:
`Warning: socket_read(): unable to read from socket [57]: Socket is not connected` when calling proccess().
Why is this? The socket is created successfully but it errors when I try to read potential incoming data.
You need to call socket_accept() to get a new socket for the incoming connection, and then read from that.
//called every 10000 microseconds to read socket
public function process(){
$connection = socket_accept($this->getSocket());
if ($connection) {
socket_set_nonblock($connection);
$buffer = socket_read($connection, 128);
var_dump($buffer);
socket_close($connection);
}
}
I know socket and thread is horrible in php... I'm just trying to connect my php file with socket to my server.
The problem is I got nothing from socket_read (no datas no error just returning an empty string) and I think pthread kill automatically the socket.
For now I don't need thread but I need to keep it to use it later.
My code:
<?php
class test extends Threaded
{
/*
*/
public function __construct($ip, $port, $debug = false)
{
$this->debug = $debug;
$this->ip = $ip;
$this->port = $port;
}
/*
*/
public function __destruct()
{
socket_close($this->connect);
}
/*
*/
public function start()
{
if (!($this->connect = socket_create(AF_INET, SOCK_STREAM, SOL_TCP))) {
throw new Exception('SOCKET_CREATE');
}
if (!socket_set_option($this->connect, SOL_SOCKET, SO_RCVTIMEO, array('sec' => 5, 'usec' => 0))) {
throw new Exception('SOCKET_SET_OPTION');
}
if (!socket_connect($this->connect, $this->ip, $this->port)) {
throw new Exception('SOCKET_CONNECT');
}
$getMsg = socket_read($this->connect, 255);
echo $getMsg;
}
}
Do you know how it can works?
EDIT: I tried again today and my script works, I don't understand sometime it works sometime not ....
EDIT2: I copied my server file script to an other server with much much more traffic and it works ! So why it works on the server 2 and not on server 1 ?
After login block the page for which this waiting(listen) for connections. Because it does not show the page post login in html?
ServerSocket.php
<?php
namespace proyectodam\Lib;
class ServerSocket{
private $address;
private $port;
public function __construct($address, $port){
set_time_limit(0);
$this->address = $address;
$this->port = $port;
$this->init();
}
private function init(){
// Create a TCP Stream socket
$sock = socket_create(AF_INET, SOCK_STREAM, 0); // 0 for SQL_TCP
// Bind the socket to an address/port
socket_bind($sock, 0, $this->port) or die('Could not bind to address'); //0 for localhost
// Start listening for connections
socket_listen($sock);
//loop and listen
while(true){
/* Accept incoming requests and handle them as child processes */
$client = socket_accept($sock);
//$_SESSION[socket_getpeername($client, AF_INET, 5555)] = socket_getpeername($client, AF_INET, 5555);
// Read the input from the client – 1024000 bytes
//$input = socket_read($client, 1024000);
// from here you need to do your database stuff
// and handle the response
// Display output back to client
socket_write($client, $response.'\n');
socket_close($client);
}
// Close the master sockets
socket_close($sock);
}
}
In the page post login
<?php
namespace\proyectodam\Lib;
new ServerSocket('127.0.0.1', 5555);
?>
<!DOCTYPE html>
<html lang="es">
.............................
</html>
ClienteSocket.java
public class ClienteSocket{
public static void main(String args[]){
try {
Socket client = new Socket("127.0.0.1", 5555);
BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
OutputStreamWriter wr = new OutputStreamWriter(client.getOutputStream());
//wr.write("data");
//wr.flush();
System.out.println(in.readLine());
} catch (IOException e) {
System.out.println("error");
e.printStackTrace();
}
}
}
Because I cannot see the HTML post login?
I don't understand what are you meaning with "HTML post login", but the php script is blocked until a connection is accepted, and this prevents the page to be sent to the browser.
I'm looking for a guide on how to use fsockopen() to communicate with a telnet system.... I'm connected just fine, but the command is failing to send. I've seen some documentation fwrite() that shows people sending some headers.
Currently the command I'm running against the telnet server is version via $class->send("version");. Do I need to send headers or anything along with this for the telnet server to pick up the command, or can I just send that?
/**
* Connect to the GMC telnet system
*/
public function connect () {
$this->connection = fsockopen($this->socket['host'], $this->socket['port'], $errorNumber, $errorMessage, 30);
if (!$this->connection) {
$this->error = 'Unable to connect to GMC: '.$errorMessage.' ('.$errorNumber.')';
return false;
}
stream_set_timeout($this->connection, $this->commandTimeout);
return true;
}
/**
* Send a command to GMC
*/
public function send ($command) {
//write to socket
if (fwrite($this->connection, $command) === false) {
$this->error = 'Unable to write to socket';
return false;
}
sleep(1);
//read socket
if (($response = fgets($this->connection)) === false) {
$this->error = 'Unable to write to socket';
return false;
}
return $response;
}
/**
* Disconnects from the GMC telnet system
*/
public function disconnect () {
return fclose($this->connection);
}
Apparently all I needed to do was be sure I included a \n at the end of my command!!
i've a class, that expects to get either an udp or tcp socket.
Now, i want to check, what kind of socket has been given to the class.
class NetClientWriter {
public __construct($socket=null) {
// do we have a socket?
if(!is_null($socket)) {
if(!is_resource($socket) ||
strtolower(get_resource_type($socket))!='socket')
throw new InvalidSocketTypeExeption("This is not a resource of type socket.");
}
// socket type
if(socket_get_option($socket, SOL_SOCKET, SO_TYPE)==SOCK_STREAM) {
echo("TCP!!!!!");
}
elseif(socket_get_option($socket, SOL_SOCKET, SO_TYPE)==SOCK_DGRAM) {
echo("UDP!!!!!");
}
else throw new InvalidSocketTypeExeption("Invalid socket type. Just UDP and TCP sockets supported.");
}
}
thanks a lot
Use socket_get_option and check for SOCK_STREAM (TCP) vs SOCK_DGRAM (UDP).