繁体   English   中英

服务器的行为好像被阻止了,但我将其设置为非阻止

[英]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)是合适的。

其次,非阻塞通信比阻塞协议难得多。 我建议您在解决这些问题之前先提高自己的网络技能,但是当您准备就绪时,请查看selectselectors模块以寻求帮助。 它们提供了等待来自多个客户端中任何一个的通信的工具,而不是像您在此处所做的那样遍历所有客户端并检查数据是否可用。 此循环效率很低。

最后,在Python中,最好使用小写,下划线分隔的名称来命名变量。 UPPER_CASE_NAMES通常为常量保留。 因此,将SERVER_SOCKET更改为server_socket ,将CONNECTED_LISTENERS更改为connected_listeners ,等等。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM