Python Socket编程 - 在监听连接时需要做点什么

4 投票
3 回答
7326 浏览
提问于 2025-04-17 13:07

我正在用Python设计一些硬件接口,具体需要做的事情如下:

~ 初始化驱动程序
~ 启动设备
~ 在2626端口创建一个套接字,并等待客户端连接以接收数据
~ 如果有客户端连接上来,就发送一个问候消息,同时服务所有其他已连接的客户端,并把这个新连接的客户端加入到已连接客户端列表中。
~ 如果设备上发生了某个事件,比如检测到温度升高,就把这个事件数据发送给所有已连接的客户端。
~ 任何已连接的客户端都可以向服务器请求特定的数据。

这是我的处理流程。设备部分现在运行得很好,数据已经能打印到控制台上。对于套接字服务器,我有以下代码,运行得也很正常。
但问题是,在调用“run()”之后,它就进入了一个循环。这是显而易见的,因为当我在监听新连接时,就无法调用其他函数。

在监听连接的同时,我应该能够发送和接收数据。有没有什么办法可以做到这一点?

这是我的服务器程序,它在监听连接时运行得很好。但是在监听的时候,你不能做其他事情。 :(

#!/usr/bin/env python

import socket
import select

class ChatServer:

    def __init__( self, port ):
        self.port = port;

        self.srvsock = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
        self.srvsock.setsockopt( socket.SOL_SOCKET, socket.SO_REUSEADDR, 1 )
        self.srvsock.bind( ("", port) )
        self.srvsock.listen( 5 )

        self.descriptors = [self.srvsock]
        print 'Server started on port %s' % port

    def run( self ):
        while 1:
            # Await an event on a readable socket descriptor
            (sread, swrite, sexc) = select.select( self.descriptors, [], [] )
            # Iterate through the tagged read descriptors
            for sock in sread:
                # Received a connect to the server (listening) socket
                if sock == self.srvsock:
                    self.accept_new_connection()
                else:
                    # Received something on a client socket
                    str = sock.recv(100)

                    # Check to see if the peer socket closed
                    if str == '':
                        host,port = sock.getpeername()
                        str = 'Client left %s:%s\r\n' % (host, port)
                        self.broadcast_string( str, sock )
                        sock.close
                        self.descriptors.remove(sock)
                    else:
                        host,port = sock.getpeername()
                        newstr = '[%s:%s] %s' % (host, port, str)
                        self.broadcast_string( newstr, sock )

    def accept_new_connection( self ):
        newsock, (remhost, remport) = self.srvsock.accept()
        self.descriptors.append( newsock )

        newsock.send("You're connected to the Python server\r\n")
        str = 'Client joined %s:%s\r\n' % (remhost, remport)
        self.broadcast_string( str, newsock )

    def broadcast_string( self, str, omit_sock ):
        for sock in self.descriptors:
            if sock != self.srvsock and sock != omit_sock:
                sock.send(str)
        print str,

myServer = ChatServer( 2626 ).run()

提前感谢大家的帮助 :)

3 个回答

1

你需要把所有的套接字设置为非阻塞模式

1

使用 Twisted

有一个例子展示了如何用核心Python进行异步网络编程,详细内容可以在 这里 找到。

1

既然不考虑使用twisted,我建议你可以用socketserver这个模块。

如果你想简单入门,可以看看这个例子

撰写回答