Python套接字.accept()在第二次调用时不起作用

2024-10-04 05:26:55 发布

您现在位置:Python中文网/ 问答频道 /正文

因此,我在一个单独的线程上运行了以下代码片段:

#Starts listening at the defined port on a separate thread. Terminates when 'stop' is received.
def start(self):
    try:
        if not self.is_running:
            self.is_running = True
            while self.is_running:
                self.socket.listen(1)
                conn, addr = self.socket.accept() 
                #Messages are split with $ symbol to indicate end of command in the stream.
                jStrs = [jStr for jStr in conn.recv(self.buffer_size).decode().split('$') if jStr != '']

                DoSomethingWith(jStrs)

    except Exception as ex:
        raise SystemExit(f"Server raised error: {ex}")

在发送方部分,我有如下内容:

#Sends a string message to the desired socket.
#@param message: The string message to send.
def send(self, message):
    if not self.connected:
        self.connect()
    self.socket.send(message.encode())
    #self.close()
    #self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

我通过套接字发送的内容以及如何使用它似乎与问题无关,因此为了清楚起见,我将其省略了。当我第一次使用send方法时,一切都正常并按预期工作。调试器运行整个While例程,并在self.socket.accept()处停止。当我在说时间之后发送同样的信息时。睡眠(2)什么也没发生。我的发送方法未被阻止,尽管我已选中

请注意发件人中的注释行。每次发送后,当我关闭连接并构建新套接字时,我没有这个问题,但为什么

当我这样做的时候,两个发送都会一个接一个地发送,没有任何时间间隔,两个都会立即到达,这是预期的行为。为什么我的self.socket.accept()在两次调用之间有一段时间间隔(甚至与打印内容所需的时间一样短)的情况下永远不会被第二次调用


Tags: thetoselfsend内容messageifis
2条回答

感谢评论中的@Alex F,我成功地解决了这个问题。看来我在错误的地方执行了循环。您不想循环self.socket.accept(),但一旦接受套接字,conn.recv()部分就会被循环。简单地将while循环移动到self.socket.accept()下面对我来说很有效

#Starts listening at the defined port on a separate thread. Terminates when 'stop' is received.
def start(self):
    try:
        if not self.is_running:
            self.is_running = True
            self.socket.listen(1)
                                    #<   moved from here
            conn, addr = self.socket.accept() 

            while self.is_running:  #<   to here
                #Messages are split with $ symbol to indicate end of command in the stream.
                jStrs = [jStr for jStr in conn.recv(self.buffer_size).decode().split('$') if jStr != '']
            
                #Loads the arguments and passes them to the remotes dictionary
                #which holds all the methods
                for jStr in jStrs: 
                    jObj = json.loads(jStr)
                    func_name = jObj["name"]
                    del jObj["name"]
                    remote.all[func_name](**jObj)

    except Exception as ex:
        raise SystemExit(f"Server raised error: {ex}")

创建套接字对象一次,然后通过它发送消息

sender = socket.socket()

def send(sender, message):
    if not sender.connected:
        sender.connect()
    sender.send(message.encode())

如果需要,您可以使用init将其封装在类中。
https://pythontic.com/modules/socket/introduction

相关问题 更多 >