I have a a logstash tcp server running which accepts a tcp socket connection, I can write to that connection on the php shell.
If I use the same code in a file I get the following lines in logstash debug console and nothing goes into my elasticsearch instance
[DEBUG] 2020-07-15 10:31:40.987 [nioEventLoopGroup-2-3] jsonlines - config LogStash::Codecs::JSONLines/#charset = "UTF-8"
[DEBUG] 2020-07-15 10:31:40.987 [nioEventLoopGroup-2-3] jsonlines - config LogStash::Codecs::JSONLines/#id = "json_lines_dbda8bcd-69ed-4356-81af-381355f76e2f"
[DEBUG] 2020-07-15 10:31:40.987 [nioEventLoopGroup-2-3] jsonlines - config LogStash::Codecs::JSONLines/#enable_metric = true
[DEBUG] 2020-07-15 10:31:40.987 [nioEventLoopGroup-2-3] jsonlines - config LogStash::Codecs::JSONLines/#delimiter = "\n"
Logstash config
input {
tcp {
port => 5080
codec => "json"
id => "PHP_TCP_LOGS"
}
}
output {
elasticsearch {
hosts => ["localhost:9200"]
index => "%{[xx]}"
}
}
PHP File
$socket = stream_socket_client('tcp://localhost:5080', $errorNumber, $error, 30);
$a = ["foo"=>"barr"];
fwrite($socket, json_encode($a) . "\n");
echo $error;
I need to send some data from a PHP server to a Node server.
Here's a simplified version of what I have so far on the PHP side:
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
$result = socket_connect($socket, '127.0.0.1', '3000');
socket_write($socket, "Hello World", 11);
socket_close($socket);
Running this code successfully sends the message to my Node server and outputs this.
However I need to send more than one message back to the socket. I actually need to send several thousand responses. But if I were to call the socket_write() function within a loop like so:
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
$result = socket_connect($socket, '127.0.0.1', '3000');
for($i=0;$i<1000;$i++){
socket_write($socket, "Hello World", 11);
}
socket_close($socket);
it seems to append all the data together and send it in one go at the end of the script. I need to send the data back in real time. Is there any way I can do this in PHP?
After looking through many PHP socket libraries, I noticed that nearly all of them just implement a usleep(1000000) after sending a socket. I'm not sure if this is the best method, but maybe it's the only way due to PHP's limitations.
In the end, I decided to store the time that data was last written to a socket. Then, calculate the time elapsed since then and subtract that from 1000000 microseconds. This way, the script will not wait longer than necessary.
public function send(array $payload){
$json = json_encode($payload);
$write = socket_write($this->socket, $json, strlen($json);
$sleep_time = 1000000 - (microtime(true) - $this->last_sent);
if($sleep_time > 0) usleep($sleep_time);
$this->last_sent = microtime(true);
return $write !== false ? true : false;
}
I'm trying to get a response from a Zebra QLn220 mobile printer via a php socket.
Communication to the printer is fine, I'm able to send config params and print the labels/receipts I need, but I can't get any response from the printer.
// Toy socket connection to Zebra QLn220 mobile printer
// set up socket
$sock = socket_create(AF_INET, SOCK_STREAM, 0);
if (!$sock){
die("boourns, no socket created");
}
echo "Socket created".PHP_EOL;
$printer_ip = '192.168.0.11';
// connect socket to printer
if(!socket_connect($sock, $printer_ip, 6101)){
$errorcode = socket_last_error();
$errormsg = socket_str($errorcode);
die("Could not connect: [$errorcode] $errormsg\n");
}
// this is actually a CPCL set up command, not ZPL, but I can't get a response regardless of language
$get_mac = '! U1 getvar "wlan.mac_addr"'
$success = socket_send($sock, $get_mac, strlen($out), 0);
$result = socket_read($sock, 1024);
echo $result.PHP_EOL;
Sending over the socket works, but I end up waiting forever and getting no response when socket_read is called.
I might be off when it comes to how to read from the socket, or perhaps the printer simply doesn't respond to any of the requests I've tried?
Other examples of messages that have been successfully transmitted over the socket, so you can see that I'm not just yelling into an abyss:
$m1 = "^XA".
"^FO20,50".
"^A0N50,50".
"^FDHello, World!".
"^FS".
"^XZ";
$m2 = "^XA".
"^FO15,60".
"^BCN,75,Y,N,N".
"^FDFront Shelf-2^FS".
"^XZ";
$m3 = "^XA".
"^POI".
"^FO50,50".
"^ADN,36,20". // height, width of characters. min is 18,10
"^FDInverted label^FS".
"^XZ";
$m4 = "^XA".
"^FO15,15".
"^FDONLY ONE LABEL?!?!^FS".
"^XZ";
$m5 = "~JC". // set media sensor calibration
"^XA".
"^JUS". // Configuration update. SAVE settings
"^XZ";
Every SGD command needs to start on a new line and be terminated with a \r\n
so add a \r\n to this line :
$get_mac = '\r\n! U1 getvar "wlan.mac_addr"\r\n'
I want a PHP script which allows you to ping an IP address and a port number (ip:port). I found a similar script but it works only for websites, not ip:port.
<?php
function ping($host, $port, $timeout)
{
$tB = microtime(true);
$fP = fSockOpen($host, $port, $errno, $errstr, $timeout);
if (!$fP) { return "down"; }
$tA = microtime(true);
return round((($tA - $tB) * 1000), 0)." ms";
}
//Echoing it will display the ping if the host is up, if not it'll say "down".
echo ping("www.google.com", 80, 10);
?>
I want this for a game server.
The idea is that I can type in the IP address and port number, and I get the ping response.
I think the answer to this question pretty much sums up the problem with your question.
If what you want to do is find out whether a given host will accept
TCP connections on port 80, you can do this:
$host = '193.33.186.70';
$port = 80;
$waitTimeoutInSeconds = 1;
if($fp = fsockopen($host,$port,$errCode,$errStr,$waitTimeoutInSeconds)){
// It worked
} else {
// It didn't work
}
fclose($fp);
For anything other than TCP it will be more difficult (although since
you specify 80, I guess you are looking for an active HTTP server, so
TCP is what you want). TCP is sequenced and acknowledged, so you will
implicitly receive a returned packet when a connection is successfully
made. Most other transport protocols (commonly UDP, but others as
well) do not behave in this manner, and datagrams will not be
acknowledged unless the overlayed Application Layer protocol
implements it.
The fact that you are asking this question in this manner tells me you
have a fundamental gap in your knowledge on Transport Layer protocols.
You should read up on ICMP and TCP, as well as the OSI Model.
Also, here's a slightly cleaner version to ping to hosts.
// Function to check response time
function pingDomain($domain){
$starttime = microtime(true);
$file = fsockopen ($domain, 80, $errno, $errstr, 10);
$stoptime = microtime(true);
$status = 0;
if (!$file) $status = -1; // Site is down
else {
fclose($file);
$status = ($stoptime - $starttime) * 1000;
$status = floor($status);
}
return $status;
}
In case the OP really wanted an ICMP-Ping, there are some proposals within the User Contributed Notes to socket_create() [link], which use raw sockets. Be aware that on UNIX like systems root access is required.
Update: note that the usec argument has no function on windows. Minimum timeout is 1 second.
In any case, this is the code of the top voted ping function:
function ping($host, $timeout = 1) {
/* ICMP ping packet with a pre-calculated checksum */
$package = "\x08\x00\x7d\x4b\x00\x00\x00\x00PingHost";
$socket = socket_create(AF_INET, SOCK_RAW, 1);
socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, array('sec' => $timeout, 'usec' => 0));
socket_connect($socket, $host, null);
$ts = microtime(true);
socket_send($socket, $package, strLen($package), 0);
if (socket_read($socket, 255)) {
$result = microtime(true) - $ts;
} else {
$result = false;
}
socket_close($socket);
return $result;
}
Test different ports:
$wait = 1; // wait Timeout In Seconds
$host = 'example.com';
$ports = [
'http' => 80,
'https' => 443,
'ftp' => 21,
];
foreach ($ports as $key => $port) {
$fp = #fsockopen($host, $port, $errCode, $errStr, $wait);
echo "Ping $host:$port ($key) ==> ";
if ($fp) {
echo 'SUCCESS';
fclose($fp);
} else {
echo "ERROR: $errCode - $errStr";
}
echo PHP_EOL;
}
// Ping example.com:80 (http) ==> SUCCESS
// Ping example.com:443 (https) ==> SUCCESS
// Ping example.com:21 (ftp) ==> ERROR: 110 - Connection timed out
Try this :
echo exec('ping -n 1 -w 1 72.10.169.28');
function ping($ip){
$output = shell_exec("ping $ip");
var_dump($output);
}
ping('127.0.0.1');
UPDATE:
If you pass an hardcoded IP (like in this example and most of the real-case scenarios), this function can be enough.
But since some users seem to be very concerned about safety, please remind to never pass user generated inputs to the shell_exec function:
If the IP comes from an untrusted source, at least check it with a filter before using it.
You can use exec function
exec("ping ".$ip);
here an example
You don't need any exec or shell_exec hacks to do that, it is possible to do it in PHP. The book 'You want to do WHAT with PHP?' by Kevin Schroeder, show's how.
It uses sockets and the pack() function which lets you read and write binary protocols. What you need to do is to create an ICMP packet, which you can do by using the 'CCnnnA*' format to create your packet.
socket_create needs to be run as root on a UNIX system with;
$socket = socket_create(AF_UNIX, SOCK_STREAM, 0);
If you want to send ICMP packets in php you can take a look at this Native-PHP ICMP ping implementation, but I didn't test it.
EDIT:
Maybe the site was hacked because it seems that the files got deleted, there is copy in archive.org but you can't download the tar ball file, there are no contact email only contact form, but this will not work at archive.org, we can only wait until the owner will notice that sit is down.
I am using the following piece of code in a php script to process incoming data over http and forward it to another module and waits for the response. It then closes the socket.
$sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
socket_bind($sock,$host,$port) or die("<?xml version=\"1.0\"?>");
if (!socket_set_option($sock, SOL_SOCKET, SO_REUSEADDR, 1)) {
echo socket_strerror(socket_last_error($sock));
exit;
}
$arrOpt = array('l_onoff' => 1, 'l_linger' => 1);
socket_set_block($sock);
socket_set_option($sock, SOL_SOCKET, SO_LINGER, $arrOpt);
$address = gethostbyname($host);
$msg = $url;
$len = strlen($msg);
socket_sendto($sock, $msg, $len, 0, $remotehost, $remoteport) ;
socket_recvfrom($sock, $buff, 1000, 0, $host, $newport);
socket_close($sock);
The problem faced is that the response is received correctly and the socket_close error is also returning a success(output of socket_last_error). But after that if I do a netstat I see the port being in used and the process (output of /proc/pid/status) is in sleep state.
This behavior is random in nature and I am using PHP version 5.3.8 on a Amazon EC2 cloud.
its about TIME_WAIT ... to free the socket
in Linux run # /proc/sys/net/ipv4/tcp_fin_timeout to find out .... (default 60 sec)
more about