When writing Socket-based server applications using PHP, socket_accept() is a key function to receive client connections. However, in some scenarios, even if the program logic is correct, socket_accept() may not receive the connection normally. This article will explain how to use strace and netstat tools to quickly locate and resolve this problem.
The following is a simple PHP server program that listens to port 8080:
<?php
$host = '0.0.0.0';
$port = 8080;
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_bind($socket, $host, $port);
socket_listen($socket);
echo "Server listening on $host:$port\n";
while (true) {
$client = socket_accept($socket);
if ($client === false) {
echo "Failed to accept connection\n";
continue;
}
$msg = "Hello from server\n";
socket_write($client, $msg, strlen($msg));
socket_close($client);
}
?>
When you find socket_accept() stuck or always return false , you need to use system tools to conduct in-depth troubleshooting.
strace is a system call tracking tool under Linux. You can directly view which system underlying functions are called by PHP scripts at runtime and their execution results.
Find the PHP process PID that is running, for example using ps :
ps aux | grep php
Use strace to attach to the process:
strace -p <PID> -e trace=network
Observe whether the following behavior exists in the output:
accept(...) = -1 : System call failed, usually accompanied by error codes (such as EAGAIN , ECONNABORTED , etc.)
Listen(...) or bind(...) error: may mean that the port is occupied or the permissions are insufficient
No call to accept() : the program may be stuck elsewhere
If strace shows accept() is normal but still has no connection access, the problem may be in the network layer or the firewall.
Netstat and SS can be used to check whether the port is in the listening state and whether there is a connection established.
netstat -tlnp | grep :8080
or:
ss -tlnp | grep :8080
You should be able to see outputs similar to the following:
tcp LISTEN 0 128 0.0.0.0:8080 0.0.0.0:* users:(("php",pid=12345,fd=3))
If there is no listening, socket_bind() or socket_listen() fails;
If the listening is normal but there is no connection, it may be that the client has not initiated the connection or is intercepted by the firewall;
If the status is CLOSE_WAIT or TIME_WAIT , it means that the connection life cycle ends abnormally.
Check for error message <br> After each Socket call, use socket_strerror(socket_last_error()) to view the specific error information.
Firewall or SELinux Limitations <br> Use iptables or firewalld to confirm that the 8080 port is not blocked.
The port is occupied by other programs <br> Use lsof -i:8080 to check if any other programs occupy the port.