You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP客户端如何持续从Python Socket服务器取数且刷新不卡顿

问题解决:PHP客户端刷新获取Python Socket服务器随机数卡顿的问题

问题根源

你的Python服务器当前只能处理单个客户端连接:服务器调用一次accept()后就进入循环处理该连接的请求,直到收到"exit"才关闭连接并退出程序。而PHP客户端每次刷新都会新建Socket连接请求,此时服务器正被第一个连接占用,无法响应新的连接请求,导致浏览器卡顿等待。

修改方案

1. 修复Python服务器:支持多客户端连接

修改服务器逻辑,让它持续监听新连接,处理完一个客户端的请求后自动释放,等待下一个连接:

import socket
import random

def getRandNum():
    randomList=[]
    lottoNums = ""
    counter = 0
    while counter < 6:
        r = random.randint(1, 40)
        if r not in randomList:
            randomList.append(r)
            counter = counter + 1
    
    lottoNums = str(randomList[0]) + "-" + str(randomList[1])+ "-" + str(randomList[2])+ "-" + str(randomList[3])+ "-" + str(randomList[4])+ "-" + str(randomList[5])    
    return lottoNums

def server_program():
    host = "127.0.0.1"
    port = 25003

    server_socket = socket.socket()
    server_socket.bind((host, port))
    server_socket.listen()
    print(f"Server listening on {host}:{port}")

    # 外层循环:持续接受新连接
    while True:
        conn, address = server_socket.accept()
        print("Connection from: " + str(address))
        
        # 内层循环:处理当前连接的请求
        while True:
            data = conn.recv(1024).decode()
            # 客户端断开连接时,recv返回空字符串
            if not data:
                break
            if data == "getNum":
                printLotto = getRandNum()
                print(printLotto)
                conn.send(printLotto.encode())
            if data == "exit":
                break
        
        # 关闭当前连接,回到外层循环等待新连接
        conn.close()
        print(f"Connection from {address} closed")

if __name__ == '__main__':
    server_program()

关键修改点:

  • 将accept()放入外层循环,服务器会持续监听新的客户端连接
  • 处理完单个客户端的请求(或客户端断开)后,关闭当前连接,回到等待状态

2. 优化PHP客户端(可选,增强稳定性)

当前PHP客户端逻辑基本正常,可添加超时处理避免极端情况卡顿:

<?php 
    $host    = "127.0.0.1";
    $port    = 25003;
    $message = "getNum";
    echo "Message To server :".$message;

    // 创建socket并设置超时
    $socket = socket_create(AF_INET, SOCK_STREAM, 0) or die("Could not create socket\n");
    socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, array('sec' => 2, 'usec' => 0));
    socket_set_option($socket, SOL_SOCKET, SO_SNDTIMEO, array('sec' => 2, 'usec' => 0));
    
    // 连接服务器
    $result = @socket_connect($socket, $host, $port);
    if (!$result) {
        die("<br>Could not connect to server\n");
    }

    // 发送请求
    $sent = socket_write($socket, $message, strlen($message));
    if (!$sent) {
        die("<br>Could not send data to server\n");
    }

    // 读取响应
    $result = socket_read($socket, 1024);
    if ($result === false) {
        die("<br>Could not read server response\n");
    }
    echo "<br>Reply From Server :".$result;
    
    // 关闭socket
    socket_close($socket);
?>

关键优化:

  • 添加socket_set_option设置读写超时,避免无限等待
  • 使用@抑制连接错误提示,配合自定义错误处理

无刷新获取随机数(AJAX实现)

修复服务器后,可通过AJAX实现无刷新获取新随机数,示例:

<!DOCTYPE html>
<html>
<body>
    <div id="randomNum"></div>
    <button onclick="getNewNum()">获取新随机数</button>
    <script>
        function getNewNum() {
            fetch('client.php')
                .then(response => response.text())
                .then(data => {
                    document.getElementById('randomNum').innerHTML = data;
                });
        }
    </script>
</body>
</html>

内容的提问来源于stack exchange,提问作者Ron

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 19:29:55