【问题标题】:Python Socket Programming - need to do something while listening for connectionsPython Socket 编程 - 在监听连接时需要做一些事情
【发布时间】:2012-02-16 06:11:38
【问题描述】:

我正在用python设计一些硬件接口。我需要做的如下,

~初始化驱动 ~启动设备 ~ 在 2626 端口创建一个套接字并等待客户端连接以接收数据 ~如果有任何客户端连接,则在为所有其他连接的客户端提供服务时发送 hello 消息,并将该客户端添加到连接的客户端列表中。 〜如果设备上发生任何事件,可以说检测到温度升高,然后通过此事件数据到所有连接的客户端。 ~任何连接的客户端都可以向服务器请求任何特定数据。

这是我的过程。我让设备部分工作得很好,现在它打印数据到控制台,对于套接字服务器,我有以下代码,正如我预期的那样工作得很好。 但问题是在调用“run()”之后它进入了 while 循环。虽然很明显。当我监听新连接时,我无法调用任何其他函数。

在侦听连接时,我应该能够发送/接收。任何想法如何做到这一点?

这是我的服务器程序,可以很好地监听连接。在听的时候,你什么都不能听。 :(

#!/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()

提前感谢您的所有帮助:)

【问题讨论】:

  • 使用Twisted?
  • @MikeCooper 感谢您的建议好友。我是 python 新手。您有任何示例吗?或者您能指出一些快速入门的教程吗?

标签: python sockets


【解决方案1】:

由于twisted 是不可能的,我建议使用socketserver 模块。

如需轻松开始,请参阅此example

【讨论】:

  • 非常感谢您的所有建议。我得到了这个与socketServer一起工作。 :)
【解决方案2】:

你需要使所有的套接字non-blocking

【讨论】:

  • @San 如果您使套接字(服务器套接字也是)非阻塞的,那么我认为您提供的代码没有问题。
  • 我也试过了。对于您的参考,我正在从 nodejs 脚本连接到此。 nodejs 以这种方式工作正常。我需要摆脱 while 循环。它停止了我的程序。
  • 在实例化类并调用 run() 方法后,如果我说 print "you can do whatever while I am listening" 这永远不会被执行。
  • @San 啊,我想我明白你的意思了!一种解决方案是为select 调用添加超时,如果超时,您可以执行其他操作,然后返回轮询套接字。另一种解决方案是将整个网络循环放在一个单独的线程中。
  • 是的,哥们,你明白我的意思。我是python的新手,一周前才开始。我不知道在单独的线程中执行套接字服务器。如果我有任何硬件事件我需要将事件数据推送到套接字,那么它会在运行中再指出一点。对此有任何想法。非常感谢这位朋友的帮助。
【解决方案3】:

使用Twisted

使用核心 python 显示异步网络的示例是 here

【讨论】:

  • ...或socketserverSocketServer for python 2.x)
  • @Kimvais 你是在说不使用扭曲的吗?我上周才开始使用 python。如果您能指出一些样品,我将更加感谢您。
  • @San - 如果你没有任何不能使用扭曲的外部限制 - 使用它。 tutorial 是一个好的开始。
  • @Kimvais - 实际上我确实有这样的限制。如果无法使用纯 python,那么我必须去做。扭曲看起来笨重。我正在编写的这些程序将在更少的内存设备上运行,而不是在大型服务器上。所以我更喜欢用纯python。
  • @san - 您可以使用核心 python 进行异步网络编程,但这会花费您更多的工作和时间,如果您是 python 的初学者,那么您将有一个陡峭的学习曲线。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-03
  • 2016-12-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多