我正在实现此example以便在简单的回显服务器中使用select
。一切正常,客户端发送消息,接收回显并断开连接。
这是我用于客户端的代码:
import socket
ECHOER_PORT = 10000
if __name__ == '__main__':
sockfd = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sockfd.connect(('localhost', ECHOER_PORT))
msg = input('Message: ').encode()
sockfd.send(msg)
response = sockfd.recv(len(msg))
print('Response: {}'.format(response))
sockfd.close()
问题出在服务器上(完整摘要代码为here),发送回显后,再次调用select
,当前客户端(接收到回显并已断开连接)从select返回为可读和可写。
根据这篇文章,我了解为什么它以可读性返回:
一个没有可用数据的可读套接字来自具有以下内容的客户端 断开连接,就可以关闭流了。
但是我的问题是为什么返回也可写?
答案 0 :(得分:1)
但是我的问题是为什么返回也可写?
当客户端断开连接时,您希望select()
要做的主要事情是立即返回,以便您的代码可以检测到断开连接事件并尽快处理(通过关闭套接字)。
一种常用的方法是,让服务器在每个套接字上进行读取选择,并且当客户端断开连接时,select()
将在该套接字上返回可供读取的内容,然后程序将在套接字上调用recv()
来查找数据,recv()
将返回EOF,服务器将关闭套接字。一切都很好。
现在想象一下服务器向其客户端套接字写入但不希望从它们读取数据的情况,这种情况很少见(但并非闻所未闻)。在这种情况下,服务器不需要(或不希望)在其套接字上进行选择以进行读取。它只需要选择准备好写入,就可以知道何时有一些传出数据缓冲区空间可用于向客户端发送更多数据。不过,该服务器仍需要知道客户端何时断开连接-这就是断开连接的套接字也选择为可写状态的原因,以便仅监视可写状态的select()
可以还可以立即检测到断开的插座并做出反应。