php version:
PHP 7.2.2 (cli) (built: Dec 16 2019 23:27:31) ( ZTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies
os is ubuntu server edition 18.04.
I tried it with php cmd.
Server code, output is "BEFORE CONNECT":
$address="127.0.0.1";
$port="3222";
$sock=socket_create(AF_INET,SOCK_STREAM,0) or die("Cannot create a socket");
socket_bind($sock,$address,$port) or die("Couldnot bind to socket");
socket_listen($sock) or die("Couldnot listen to socket");
var_dump('BEFORE ACCEPT');
$accept=socket_accept($sock) or die("Couldnot accept");
$read=socket_read($accept,1024) or die("Cannot read from socket");
echo $read;
socket_write($accept,"Hello client");
socket_close($sock);
Client code:
$address="127.0.0.1";
$port="3222";
$msg="Hello server";
$sock=socket_create(AF_INET,SOCK_STREAM,0) or die("Cannot create a socket");
var_dump('BEFORE CONNECT');
socket_connect($sock,$address,$port) or die("Could not connect to the socket");
socket_write($sock,$msg);
$read=socket_read($sock,1024);
echo $read;
socket_close($sock);
The problem is that client script hangs with socket_connect() function and after sometime I get:
Warning: socket_connect(): unable to connect [110]: Connection timed out in "script"
But on my local Ubuntu 18.04.3 LTS it works. PHP is the same.
I also tried to create server on external ip and access it from outside, same result - it hangs. But if I change the port to wrong on client - I got warning immediately: Warning: socket_connect(): unable to connect [111]: Connection refused in
The following configurations are added to ubuntu:
/etc/sysctl.conf file:
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.secure_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.tcp_max_orphans = 65536
net.ipv4.tcp_fin_timeout = 10
net.ipv4.tcp_keepalive_time = 1800
net.ipv4.tcp_keepalive_intvl = 15
net.ipv4.tcp_keepalive_probes = 5
net.ipv4.tcp_max_syn_backlog = 4096
net.ipv4.tcp_synack_retries = 1
net.ipv4.tcp_mem = 50576 64768 98152
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
net.ipv4.tcp_orphan_retries = 0
net.ipv4.tcp_syncookies = 0
net.ipv4.netfilter.ip_conntrack_max = 16777216
net.netfilter.nf_conntrack_max = 16777216
net.ipv4.tcp_timestamps = 1
net.ipv4.tcp_sack = 1
net.ipv4.tcp_congestion_control = htcp
net.ipv4.tcp_no_metrics_save = 1
net.ipv4.route.flush = 1
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.lo.rp_filter = 1
net.ipv4.conf.eth0.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.lo.accept_source_route = 0
net.ipv4.conf.eth0.accept_source_route = 0
net.ipv4.conf.default.accept_source_route = 0
net.ipv4.ip_local_port_range = 1024 65535
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_window_scaling = 1
net.ipv4.tcp_rfc1337 = 1
net.ipv4.ip_forward = 0
net.ipv4.icmp_echo_ignore_broadcasts = 1
net.ipv4.icmp_echo_ignore_all = 1
net.ipv4.icmp_ignore_bogus_error_responses = 1
net.core.somaxconn = 65535
net.core.netdev_max_backlog = 1000
net.core.rmem_default = 65536
net.core.wmem_default = 65536
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
fs.inotify.max_user_watches = 16777216
And:
sysctl -w fs.file-max=12000500
sysctl -w fs.nr_open=20000500
# Set the maximum number of open file descriptors for current shell session
ulimit -n 20000000
/etc/security/limits.conf
# <domain> <type> <item> <value>
* soft nofile 20000
* hard nofile 20000
# Set the memory size for TCP with minimum, default and maximum thresholds
sysctl -w net.ipv4.tcp_mem='10000000 10000000 10000000'
# Set the receive buffer for each TCP connection with minumum, default and maximum thresholds
sysctl -w net.ipv4.tcp_rmem='1024 4096 16384'
# Set the TCP send buffer space with minumum, default and maximum thresholds
sysctl -w net.ipv4.tcp_wmem='1024 4096 16384'
# The maximum socket receive buffer sizemem_max=16384
sysctl -w net.core.rmem_max=16384
# The maximum socket send buffer size
sysctl -w net.core.wmem_max=16384
Is it possible that some of those configurations make socket_connect hangs ?
Ah, and the firewall status is inactive , checked with sudo ufw status
The same code works on 2 other same ubuntu installation with same PHP compilation.
By the way, mysql and apache2 work well on that machine.
It looks like server script doesn't accept the connection, I mean this code socket_accept($sock) because I tried to connect with client php script, tried to connect with telnet, and also I tried to create server on external ip and when I tried to connect to it from my another computer - the same situation, socket_connect hangs. Seems like server doesn't accept connection..
Also I tried php socket server with non blocking mode:
$address="127.0.0.1";
$port="3222";
$sock=socket_create(AF_INET,SOCK_STREAM,0) or die("Cannot create a socket");
socket_bind($sock,$address,$port) or die("Couldnot bind to socket");
socket_listen($sock) or die("Couldnot listen to socket");
socket_set_nonblock($sock);
var_dump('BEFORE ACCEPT');
while (1) {
if($accept=socket_accept($sock)) {
$read=socket_read($accept,1024) or die("Cannot read from socket");
echo $read;
socket_write($accept,"Hello client");
socket_close($sock);
die;
}
sleep(1);
}
So server tries to accept connection each 1 second. But still same result((
It is crazy because if I create the server as following, it works:
$address="127.0.0.1";
$port="3222";
$socket = stream_socket_server("tcp://{$address}:{$port}", $errno, $errstr);
if (!$socket) {
echo "$errstr ($errno)<br />\n";
} else {
while ($conn = stream_socket_accept($socket)) {
fwrite($conn, 'Локальное время ' . date('n/j/Y g:i a') . "\n");
fclose($conn);
}
fclose($socket);
}
And one more moment, analogical python script works well!
Python server:
#!/usr/bin/env python3
import socket
HOST = '127.0.0.1' # Standard loopback interface address (localhost)
PORT = 33 # Port to listen on (non-privileged ports are > 1023)
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind((HOST, PORT))
s.listen()
conn, addr = s.accept()
with conn:
print('Connected by', addr)
while True:
data = conn.recv(1024)
if not data:
break
conn.sendall(data)
Python client:
#!/usr/bin/env python3
import socket
HOST = '127.0.0.1' # The server's hostname or IP address
PORT = 33 # The port used by the server
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((HOST, PORT))
s.sendall(b'Hello, world')
data = s.recv(1024)
print('Received', repr(data))
But why does not PHP work ? What might be the problem ?
PHP recompilation did not help((