[英]The server is behaving as if it is blocked but i have set it to non blocking
服务器仅侦听来自第一个套接字的消息以进行连接,即使将其设置为非阻塞,也不会在不接收数据时跳过该消息。 我是网络新手,这是我的第一个项目,如果有人知道其他对初学者有好处的人,请告诉我。 谢谢! 这是代码。
import socket
CONNECTED_SENDERS = []
CONNECTED_LISTENERS = []
def Main():
HOST = socket.gethostname()
PORT = 4444
SERVER_SOCKET = socket.socket()
SERVER_SOCKET.bind((HOST, PORT))
SERVER_SOCKET.listen(1)
for i in range(2):
CONNECTION, ADDRESS = SERVER_SOCKET.accept()
CONNECTED_LISTENERS.append(CONNECTION)
for i in range(2):
CONNECTION, ADDRESS = SERVER_SOCKET.accept()
CONNECTED_SENDERS.append(CONNECTION)
for DEVICE in CONNECTED_LISTENERS:
DEVICE.send(b'SERVER: You have succesfully connected.')
DEVICE.send(b'SERVER: Please wait for permission to talk.')
x = 0
for DEVICE in CONNECTED_LISTENERS:
DEVICE.send(b'SERVER: What is your name?')
Name = CONNECTED_SENDERS[x].recv(1024)
CONNECTED_LISTENERS[x] = (CONNECTED_LISTENERS[x], Name)
x += 1
del x, Name
for DEVICE, _ in CONNECTED_LISTENERS:
DEVICE.send(b'SERVER: You may now talk.')
SERVER_SOCKET.setblocking(0)
LEAVE = False
while LEAVE == False:
try:
MESSAGE = CONNECTED_SENDERS[0].recv(1024)
NAME = CONNECTED_LISTENERS[0][1]
for DEVICE, _ in CONNECTED_LISTENERS:
DEVICE.send(NAME + b': ' + MESSAGE)
if MESSAGE == 'QUIT':
LEAVE = True
except:
try:
MESSAGE = CONNECTED_SENDERS[1].recv(1024)
NAME = CONNECTED_LISTENERS[1][1]
for DEVICE, _ in CONNECTED_LISTENERS:
DEVICE.send(NAME + b': ' + MESSAGE)
if MESSAGE == 'QUIT':
LEAVE = True
except:
pass
for CONNECTION in CONNECTED_LISTENERS:
CONNECTION.close()
for CONNECTION in CONNECTED_SENDERS:
CONNECTION.close()
if __name__ == "__main__":
Main()
您的代码有很多问题,有些很小,有些很大。 但是主要的问题是,您正在标记服务器套接字为非阻塞状态,而不是在其上进行通信的任何套接字。
在标准TCP套接字编程中,您将设置一个服务器来侦听传入的连接。 当该服务器接受新客户端时,它将返回一个新的套接字,并且在该新套接字上发生了与远程客户端的所有通信。 换句话说,服务器套接字仅用于接受新的连接,而没有别的。 您永远不会通过服务器套接字写入数据。
因此,将SERVER_SOCKET
标记为非阻塞并不重要,您必须执行以下操作:
conn, addr = server.accept()
conn.setblocking(False)
conn
是新的套接字,您可以通过它与客户端进行通信,并且可以以非阻塞方式使用。
我还应该指出,您调用SERVER_SOCKET.listen(1)
。 该参数1
表示服务器将仅积压来自一个客户端的等待连接。 因此,如果在建立第一个连接之前连接了第二个客户端,则第二个客户端将收到错误ECONNREFUSED
。 考虑到您要尝试执行的操作,我认为SERVER_SOCKET.listen(4)
是合适的。
其次,非阻塞通信比阻塞协议难得多。 我建议您在解决这些问题之前先提高自己的网络技能,但是当您准备就绪时,请查看select
或selectors
模块以寻求帮助。 它们提供了等待来自多个客户端中任何一个的通信的工具,而不是像您在此处所做的那样遍历所有客户端并检查数据是否可用。 此循环效率很低。
最后,在Python中,最好使用小写,下划线分隔的名称来命名变量。 UPPER_CASE_NAMES
通常为常量保留。 因此,将SERVER_SOCKET
更改为server_socket
,将CONNECTED_LISTENERS
更改为connected_listeners
,等等。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.