PHP UDP服务器连接失败:远程主机拒绝连接问题排查
问题分析与解决:Telnet无法连接UDP服务器
你遇到的问题核心其实很直白——Telnet是基于TCP协议的工具,但你的服务器是用UDP协议实现的,这俩协议完全不兼容,所以Telnet尝试发起TCP连接时自然会被拒绝,毕竟你的UDP服务器根本没在监听TCP的21665端口。
先搞懂核心差异:TCP vs UDP
- TCP是面向连接的协议:通信前必须完成三次握手建立连接,Telnet、HTTP这类工具/协议都依赖这个机制;
- UDP是无连接的协议:不需要提前建立连接,数据报直接发送即可,你的代码里用的
SOCK_DGRAM就是UDP套接字的标识。
两种解决方案,看你的实际需求
情况1:你确实需要UDP服务器,只是想测试它
用支持UDP的工具来测试就行,nc(netcat)是大多数系统都自带的工具,操作步骤如下:
- 保持你的UDP服务器后台运行(
php server.php); - 打开新终端执行:
nc -u 127.0.0.1 21665; - 现在输入任意内容回车,服务器端就会输出
Client submitted request!了。
如果你的系统没有nc,也可以自己写个简单的UDP客户端脚本:
// client.php $server_host = '127.0.0.1'; $server_port = 21665; $socket = socket_create(AF_INET, SOCK_DGRAM, 0); $message = "Hello UDP Server!"; socket_sendto($socket, $message, strlen($message), 0, $server_host, $server_port); socket_close($socket);
执行php client.php,服务器端就能收到请求提示。
情况2:你其实需要TCP服务器(想让Telnet能连接)
那得把服务器代码改成TCP版本,核心是替换套接字类型并添加TCP特有的监听、连接逻辑:
// tcp_server.php $server_host = '127.0.0.1'; $server_port = 21665; $poll_interval = 0.5; // 将SOCK_DGRAM改为SOCK_STREAM(TCP套接字类型) $socket = socket_create(AF_INET, SOCK_STREAM, 0); socket_bind($socket, $server_host, $server_port); // TCP必须调用listen监听连接请求 socket_listen($socket); $clients = [$socket]; while(true) { $read = $clients; $write = []; $except = []; if (socket_select($read, $write, $except, $poll_interval) < 1){ continue; } if (in_array($socket, $read)) { // 接受新的TCP连接 $new_client = socket_accept($socket); $clients[] = $new_client; echo "New client connected!\n"; } else { // 处理已连接客户端的消息 foreach($read as $client_socket) { $data = socket_read($client_socket, 1024); if ($data === false || empty($data)) { // 客户端断开连接,清理资源 $index = array_search($client_socket, $clients); unset($clients[$index]); socket_close($client_socket); echo "Client disconnected!\n"; } else { echo "Client submitted request: $data\n"; // 可选:回复客户端消息 socket_write($client_socket, "Received your message: $data"); } } } }
现在执行php tcp_server.php,再用telnet 127.0.0.1 21665就能正常连接,输入消息服务器也能收到并回复了。
内容的提问来源于stack exchange,提问作者Jacobian




