“Address already in use”错误表明目标端口被其他进程占用,需先用lsof或netstat定位PID,再kill清理;若为Workerman残留进程可用killall php或ps+awk强制终止;切勿盲目换端口,应先确认是否因未执行stop导致的假未启动。

Address already in use:端口被占用了
这是最常见的情况,stream_socket_server() 启动时提示 “Address already in use”,说明你要监听的端口(比如 8282 或 1236)正被另一个进程占用。
别急着改代码,先查谁在用:
- Linux/macOS:
sudo lsof -i :8282或netstat -tuln | grep :8282 - Windows:
netstat -ano | findstr :8282,再用taskkill /F /PID 12345杀掉对应 PID
如果杀不掉(比如 Workerman 主进程残留),可强制清理:
killall php- 或
ps aux | grep Worker | awk '{print $2}' | xargs kill -9
注意:别盲目换端口,先确认是否是自己上一次没 stop 就直接关终端导致的假“未启动”。
Cannot assign requested address:IP 地址写错了
报错里出现 Cannot assign requested address,基本等于你在 stream_socket_server() 的 $address 参数里填了个本机根本不存在的 IP,比如写了公网 IP(腾讯云/阿里云服务器上尤其常见)但该 IP 并不实际绑定在网卡上。
正确做法是:
- 查真实本地 IP:
ip addr(Linux)或ipconfig(Windows),找inet行里带192.168.x.x、10.x.x.x或172.16–31.x.x的地址 - 更省事:直接用
0.0.0.0:8282,表示监听所有本地网卡 —— 这是绝大多数开发场景的合理选择 - 别用云厂商控制台显示的“公网 IP”,它通常只是 NAT 映射,不能用于
bind()
Permission denied:权限或系统限制拦住了
Windows 上报 “以一种访问权限不允许的方式做了一个访问套接字的尝试”,或 Linux 上报 Permission denied,原因分两类:
- 端口
(如 <code>80、443):Linux 默认只允许 root 绑定,非 root 用户要么加sudo,要么换 ≥1024 的端口(推荐) - Windows 下 Winsock 资源耗尽:长时间运行后出现
insufficient winsock resources,不是权限问题,而是 socket 句柄泄漏 —— 检查代码里是否漏了stream_socket_shutdown()或fclose() - PHP 层面禁用:检查
php --ini找到的php.ini,确认disable_functions里没禁掉stream_socket_server
防火墙或安全组没放行:连得上但通不了
服务明明启动成功,客户端却连不上(比如 WebSocket 报 net::ERR_CONNECTION_TIMED_OUT),大概率是流量被拦在半路。
排查顺序:
- 本地测试:用
telnet 127.0.0.1 8282或curl -v telnet://localhost:8282看能否建立 TCP 连接(不涉及应用层协议) - Linux 防火墙:
sudo firewall-cmd --list-ports,没看到你的端口就加:sudo firewall-cmd --add-port=8282/tcp --permanent && sudo firewall-cmd --reload - 云服务器(腾讯云/阿里云):必须去控制台「安全组」里手动添加入方向规则,开放对应端口 —— 宝塔用户在「安全」→「放行端口」里操作也一样
注意:Windows 防火墙默认会拦截非标准端口,要进「高级安全 Windows Defender 防火墙」→「入站规则」里新建一条允许 TCP 端口的规则。


















