gpt4 book ai didi

Python套接字: Server waits for nothing when asked to 'recv' and then 'sendall'

转载 作者:行者123 更新时间:2023-12-01 02:32:40 26 4
gpt4 key购买 nike

我正在尝试使用 python 套接字来尝试更好地理解整个概念,但我遇到了问题。我有一个简单的服务器和一个客户端,客户端向服务器发送一个列表,然后等待服务器发送一个字符串,表示该过程已完成。

这是客户端文件:

import socket
import json


host = '192.168.1.102'
port = 14314


def request():

print 'Connecting'
clientsocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
clientsocket.connect((host, port))

print 'Sending request'
clientsocket.sendall(json.dumps([1, 2, 3, 4, 5, 6, 7, 8, 9]))

print 'Receiving data'
data = clientsocket.recv(512)
print 'Received: {}'.format(data)


request()

这是服务器文件:

import socket
import json


host = '192.168.1.102'
port = 14314


def run():

print 'Binding socket'
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serversocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
serversocket.bind((host, port))

print 'Waiting for client'
serversocket.listen(1)
clientsocket, addr = serversocket.accept()

print 'Receiving data'
raw_data = ''
while True:
tmp = clientsocket.recv(1024)
if not tmp:
break
raw_data += tmp
data = json.loads(raw_data)
print 'Received: {}'.format(data)

print 'Sending data'
clientsocket.sendall('done')


run()

问题在于,当客户端发送完列表后,服务器陷入了recv循环,什么也不等待。在第一次迭代中已接收到全部数据,在第二次迭代中没有接收到任何内容,因为客户端已移至接收部分。

奇怪的是,如果我注释掉来自客户端的接收部分和来自服务器的发送部分,该过程就会成功完成。那么,我做错了什么?为什么这不起作用?

谢谢。

最佳答案

socket.recv 的文档谈论能够传递到 unix 文档中描述的 recv 函数的附加标志。所以转向documentation ,我发现以下消息:

If no messages are available at the socket, the receive calls wait for a message to arrive, unless the socket is nonblocking (see fcntl(2)), in which case the value -1 is returned

因此,我们再次被引导到另一个页面。 fcntl 的文档说

Performs one of the operations described below on the open file descriptor

因此,通常情况下,socket.recv 函数是阻塞的(它将无限期地等待新数据),除非我们使用文件描述符。我们该怎么做呢?嗯,有一个socket.makefile函数为我们提供了附加到套接字的文件描述符。凉爽的。这个SO question为我们提供了如何使用文件描述符读取和写入套接字的示例。

如果我们不想使用文件描述符怎么办?进一步阅读有关 recv 函数的 unix 文档,我发现可以使用 MSG_DONTWAIT 标志。这在 Windows 中不起作用,但我确实发现我们可以使用 socket.setbocking(False)将套接字永久更改为非阻塞模式。然后,您需要忽略任何“无法立即完成非阻塞套接字操作”错误。这些都是正常且非致命的(this page 的错误 #10035 提到它是非致命的)。

另一种可能的实现是对程序进行多线程,您可以为套接字实现接收和发送线程。这可能会给您带来最佳性能,但设置工作量很大。

Python 很棒。我刚刚发现 Python 的一些库也可以实现异步套接字。有asyncore , asynchat它们均已被弃用,取而代之的是 asyncio如果您正在使用的 Python 版本中提供该功能。

抱歉扔了这么多。我对套接字不太了解。我在 Paramiko 库中使用过一次,仅此而已。但看起来有很多实现它们的方法。

关于Python套接字: Server waits for nothing when asked to 'recv' and then 'sendall' ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46625163/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com