如何在python中实现非阻塞套接字服务器

Zac*_*Zac 5 python sockets multithreading nonblocking blocking

一个类似但不同的问题:

我有一个生成字符串的 IRC 客户端。这个 IRC 客户端使用一个钩子来调用一个方法 (somone_said) 每当有人说的话。我想通过套接字将此字符串发送到我的 Flash 客户端。

我有一个在 flash 中工作的客户端和一个在 python 中的服务器,但问题是它阻塞:1)在侦听客户端连接时 2)在等待生成下一条消息时

这会阻止 IRC 客户端响应其他输入。

我想我需要在一个单独的线程中创建我的套接字,但这又产生了三个问题。1)我的someone_said事件驱动方法如何访问套接字2)如果有人在没有服务器客户端连接(在侦听时)或客户端关闭连接时说了些什么怎么办。3)如何检查线程是否处于活动状态,如果没有打开一个新线程?

我的阻塞服务器代码是这样的:

# Echo server program
import socket
import sys

HOST = None               # Symbolic name meaning all available interfaces
PORT = 7001              # Arbitrary non-privileged port
s = None

def startListening():
    print "starting to listen"

    for res in socket.getaddrinfo(HOST, PORT, socket.AF_UNSPEC,
                                  socket.SOCK_STREAM, 0, socket.AI_PASSIVE):
        af, socktype, proto, canonname, sa = res
        try:
            s = socket.socket(af, socktype, proto)
        except socket.error as msg:
            s = None
            continue
        try:
            s.bind(sa)
            s.listen(1)
        except socket.error as msg:
            s.close()
            s = None
            continue
        break
    if s is None:
        print 'could not open socket'
        sys.exit(1)
    conn, addr = s.accept()
    print 'Connected by', addr
    while 1:
        try: 
            data = conn.recv(1024)
        except:
            print "cannot recieve data"
            break
        if not data: 
            break
        print data
        message = ""
        while not "quit" in message:
            message = raw_input('Say Something : ') # This will come from event driven method
            try: 
                conn.sendall(message)
            except Exception as exc:
                print "message could not be sent"
                break


    conn.close()
    print "connection closed"

while 1:
    startListening()
Run Code Online (Sandbox Code Playgroud)

xchat 模块 python 脚本是这样工作的(需要运行 HexChat)

__module_name__ = "Forward Module"
__module_version__ = "1.0.0"
__module_description__ = "Forward To Flash Module by Xcom"

import sys
import xchat

def someone_said(word, word_eol, userdata):
    # method called whenever someone speaks in IRC channel
    username = str(word[0]) # From IRC contains the username string
    message = str(word[1]) # From IRC contains the user message
    sendString = username + " : " + message
    send_to_server(sendString)


def send_to_server(message):
    # send over socket method to be implemented here

xchat.hook_print('Channel Message' , someone_said)
Run Code Online (Sandbox Code Playgroud)

几天来我一直在用头撞这堵墙。帮助我 obi wan kenobi,你是我唯一的希望。

Kor*_*eth 4

看看 Asyncore,它完全适合您正在寻找的东西:)

http://docs.python.org/2/library/asyncore.html

干杯,

K.

  • Python 为您提供了使用 `socket.setblocking(0)` 的能力,之后您的套接字将是非阻塞的。主要文档可在此处获取(http://docs.python.org/2/howto/sockets.html#non-blocking-sockets),您还可以在此处进行一些利用(http://pymotw.com/2/select /index.html)。 (2认同)