当客户端断开连接时,为什么 `select()` 将客户端返回为可写?
Why is `select()` returning a client as writable when the client has disconnected?
我正在实施此 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 return 编辑为可读和可写。
我理解为什么它 return 被编辑为可读的,因为根据文章:
A readable socket without data available is from a client that has
disconnected, and the stream is ready to be closed.
但我的问题是为什么 return 也是可写的?
But my question is why does return as writable also?
当客户端断开连接时,您希望 select()
做的主要事情是立即 return,以便您的代码可以检测到断开连接事件并尽快处理它(通过关闭套接字).
一种常见的方法是让服务器 select-for-read 在每个套接字上读取,当客户端断开连接时,select()
将 return 准备好-for-read 在该套接字上,然后程序将在套接字上调用 recv()
以查明数据是什么,recv()
将 return EOF,服务器将关闭套接字。一切都很好。
现在想象一下服务器写入其客户端套接字但不想从中读取的不太常见(但并非闻所未闻)的情况。在这种情况下,服务器不需要(或不希望)select 在其套接字上准备好读取;它只需要 select 就可以写入,知道何时有一些传出数据缓冲区 - space 可用于向客户端发送更多数据。但是,该服务器仍然需要知道客户端何时断开连接——这就是为什么断开连接的套接字 selects 也准备好写入,因此 select()
只在等待准备就绪-for-write 还可以立即检测断开连接的套接字并对其做出反应。
我正在实施此 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 return 编辑为可读和可写。
我理解为什么它 return 被编辑为可读的,因为根据文章:
A readable socket without data available is from a client that has disconnected, and the stream is ready to be closed.
但我的问题是为什么 return 也是可写的?
But my question is why does return as writable also?
当客户端断开连接时,您希望 select()
做的主要事情是立即 return,以便您的代码可以检测到断开连接事件并尽快处理它(通过关闭套接字).
一种常见的方法是让服务器 select-for-read 在每个套接字上读取,当客户端断开连接时,select()
将 return 准备好-for-read 在该套接字上,然后程序将在套接字上调用 recv()
以查明数据是什么,recv()
将 return EOF,服务器将关闭套接字。一切都很好。
现在想象一下服务器写入其客户端套接字但不想从中读取的不太常见(但并非闻所未闻)的情况。在这种情况下,服务器不需要(或不希望)select 在其套接字上准备好读取;它只需要 select 就可以写入,知道何时有一些传出数据缓冲区 - space 可用于向客户端发送更多数据。但是,该服务器仍然需要知道客户端何时断开连接——这就是为什么断开连接的套接字 selects 也准备好写入,因此 select()
只在等待准备就绪-for-write 还可以立即检测断开连接的套接字并对其做出反应。