PHP socket_read / recv阻塞python的socket.send

时间:2016-04-07 15:20:20

标签: php python sockets send recv

我正在使用JS + PHP客户端在Linux上用Python构建Firebird DB事务管理器。 Javascript将所有必要的信息发送给PHP; PHP对此进行编码并通过套接字将其发送到Python,Python有一个绑定到端口的套接字不断监听并使用线程创建一个新线程来异步处理该请求。

python中的accept循环:

while 1:
    conn, addr = s.accept()

    req = conn.recv(1024)
    ret = read_headers(req)

    threading.Thread(target=client_thread, args=(conn, addr, ret, smphr,)).start()
s.close()

php中的发送/读取块:

$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
$sockconnect = socket_connect($sock, $host, $port);
$msg = urldecode(http_build_query($params));
socket_write($sock, $msg, strlen($msg));
$received;
while(socket_recv($sock, $buf, 1024, 0) >= 1){
    $received .= $buf;
}
echo $received;
socket_close($sock);

在我们开始使用大量连接进行测试之前,这一切似乎都正常工作。我在JS客户端中有一个循环,它发送了几个(目前为止我用过的数字是25-100个)查询请求,并从一个大表中选择第一个随机数行。

服务器收到的前几个请求会同时处理,但后来似乎变得同步。

经过大量日志记录后,发现在任何给定时间只有7/8个线程处于活动状态。新请求仅在7个当前请求中的一个完成后被接受和处理。

如果我在php中注释socket_recv while循环,那么python将同时运行所有内容并尽快返回,这正是我想要的,但是因为我已经评论了实际获得结果的块,所以没有什么是显示(显然)。

每个请求/查询都记录为不同的脚本调用(根据chrome的网络开发工具),所以我不知道为什么他们互相阻塞。

我在php / python上相当新,我不能为我的生活找出正在发生的事情。

有什么建议吗?

编辑: 我也尝试了不同的代码来读取php中的响应(没有按预期工作):

$buf = 'buffer';
socket_recv($sock, $buf, 1024, MSG_WAITALL);
echo $buf;

与之前的实施相同,7/8线程'限制'

$buf = 'buffer';
socket_recv($sock, $buf, 1024, MSG_DONTWAIT);
echo $buf;

如标志所示,不等待响应,因此没有响应

while ($out = socket_read($sock, 1024, PHP_NORMAL_READ)) {
    echo $out;
}

相同的线程7/8线程限制。

第二次编辑:

添加了Python打印件,以防万一。

阅读php

starting select first 3000 * from receb_quotas on tr1
starting select first 1 * from receb_quotas on tr0
starting select first 1 * from receb_quotas on tr2
starting select first 1 * from receb_quotas on tr4
starting select first 3000 * from receb_quotas on tr3
starting select first 3000 * from receb_quotas on tr5
finishing tr4 (count: 1) | remaining threads: 7
finishing tr0 (count: 1) | remaining threads: 7
starting select first 150 * from receb_quotas on tr8
starting select first 3000 * from receb_quotas on tr6
finishing tr2 (count: 1) | remaining threads: 7
starting select first 1 * from receb_quotas on tr7
finishing tr7 (count: 1) | remaining threads: 7
starting select first 3000 * from receb_quotas on tr9
finishing tr8 (count: 150) | remaining threads: 7
finishing tr1 (count: 3000) | remaining threads: 6
finishing tr3 (count: 3000) | remaining threads: 5
finishing tr6 (count: 3000) | remaining threads: 4
finishing tr5 (count: 3000) | remaining threads: 3
finishing tr9 (count: 3000) | remaining threads: 2

没有php阅读

starting select first 3000 * from receb_quotas on tr1
starting select first 15 * from receb_quotas on tr0
starting select first 15 * from receb_quotas on tr3
starting select first 3000 * from receb_quotas on tr4
starting select first 1500 * from receb_quotas on tr2
starting select first 150 * from receb_quotas on tr5
starting select first 1 * from receb_quotas on tr6
starting select first 1500 * from receb_quotas on tr7
starting select first 150 * from receb_quotas on tr8
starting select first 15 * from receb_quotas on tr9
finishing tr0 (count: 15) | remaining threads: 11
finishing tr3 (count: 15) | remaining threads: 10
finishing tr6 (count: 1) | remaining threads: 9
finishing tr9 (count: 15) | remaining threads: 8
finishing tr8 (count: 150) | remaining threads: 7
finishing tr5 (count: 150) | remaining threads: 6
finishing tr7 (count: 1500) | remaining threads: 5
finishing tr2 (count: 1500) | remaining threads: 4
finishing tr1 (count: 3000) | remaining threads: 3
finishing tr4 (count: 3000) | remaining threads: 2

看起来似乎没有在php中读取,查询都会在同一时间启动并在准备好后立即返回。

1 个答案:

答案 0 :(得分:0)

原来这是一个浏览器问题。 Chrome(可能是其他现代浏览器)同时最多只支持6个ajax调用。

因为我有7个线程'cap',其中一个是主线程。这完美排列。