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

时间:2018-03-19 18:01:09

标签: python networking

服务器只侦听来自第一个要连接的套接字的消息,即使它被设置为非阻塞,它也不会在它不接收数据时跳过它。我是网络新手,这是我的第一个项目,如果有人知道任何其他适合初学者的人请告诉我。谢谢!这是代码。

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()

1 个答案:

答案 0 :(得分:1)

您的代码存在许多问题,有些是小问题,有些是大问题。但主要问题是您将服务器套接字标记为非阻塞,而不是任何进行通信的套接字

在标准TCP套接字编程中,您设置一个侦听传入连接的服务器。当该服务器接受新客户端时,将返回 new 套接字,并且在此新套接字上将发生与远程客户端的所有通信。换句话说,服务器套接字仅用于接受新连接,而不是其他任何东西。您永远不会通过服务器套接字写入数据。

因此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,等等。