我有一个运行中的扭曲反应器,如何连接?

1 投票
1 回答
1894 浏览
提问于 2025-04-17 07:41

我一直在跟着教程,现在已经有了一个运行中的 Twisted reactor(反应器)。我用 telnet 测试过它能正常工作,但在 Twisted 的教程中找不到关于如何连接到这个反应器的内容。

我原本以为 Twisted 里面会有相关的功能,但我是不是应该直接使用内置的 socket(套接字)呢?

编辑:

这是服务器脚本:

import time
import multiprocessing

from twisted.internet.protocol import Factory
from twisted.protocols.basic import LineReceiver
from twisted.internet import reactor

class TTT(LineReceiver):
    def __init__(self, users):
        self.users = users
        self.name = None
        self.state = "GETNAME"

    def connectionMade(self):
        self.sendLine("You are connected")

    def connectionLost(self, reason):
        if self.users.has_key(self.name):
            del self.users[self.name]

    def lineReceived(self, line):
        if line == "quit":
            reactor.stop()

        if self.state == "GETNAME":
            self.handle_GETNAME(line)
        else:
            self.handle_CHAT(line)

    def handle_GETNAME(self, name):
        if self.users.has_key(name):
            self.sendLine("Name taken, please choose another.")
            return
        self.sendLine("Welcome, %s!" % (name,))
        self.name = name
        self.users[name] = self
        self.state = "CHAT"

    def handle_CHAT(self, message):
        message = "<%s> %s" % (self.name, message)
        for name, protocol in self.users.iteritems():
            if protocol != self:
                protocol.sendLine(message)


class TTTFactory(Factory):
    def __init__(self):
        self.state = [0 for x in range(9)]
        self.turn = -1

        self.users = {} # maps user names to Chat instances

    def make_move(self, player, x, y):
        if player != self.turn:
            return "Not your turn"

        i = x + y * 3

        if self.state[i] != 0:
            return "Invalid move"

        self.state[i] = player

        # Horrizontal
        if self.state[0] == self.state[1] == self.state[2]: return "Win"
        if self.state[3] == self.state[4] == self.state[5]: return "Win"
        if self.state[6] == self.state[7] == self.state[8]: return "Win"

        # Vertical
        if self.state[0] == self.state[3] == self.state[6]: return "Win"
        if self.state[1] == self.state[4] == self.state[7]: return "Win"
        if self.state[2] == self.state[5] == self.state[8]: return "Win"

        # Diagonal
        if self.state[0] == self.state[4] == self.state[8]: return "Win"
        if self.state[6] == self.state[4] == self.state[2]: return "Win"

        # Swap turn
        self.turn = 0 - self.turn
        return "Next move"

    def buildProtocol(self, addr):
        return TTT(self.users)

# def reactor_runner():
def new_server(conn):
    port_num = 8007
    conn.send(port_num)

    reactor.listenTCP(port_num, TTTFactory())
    reactor.run()

我想让另一个 Python 程序或进程能够发送和接收消息。这个项目的想法是创建一个多人井字棋游戏。

我想要有一个服务器进程和一个或多个客户端进程。为了方便运行,我目前使用多进程同时运行它们。完成后,客户端进程需要能够通过网络连接,因为它可能不在和主机同一台电脑上。

1 个回答

3

这里有一个简单的例子,展示了一个可以连接到你上面提到的服务器的客户端。

from twisted.internet.protocol import ClientFactory
from twisted.protocols.basic import LineReceiver
from twisted.internet import reactor

class TTTClientProtocol(LineReceiver):
    def lineReceived(self, line):
        line = line.strip()
        if line == 'You are connected':
            self.sendLine(self.factory.username)
        else:
            print 'SERVER SAYS:', line

class TTTClientFactory(ClientFactory):
    protocol = TTTClientProtocol 

    def __init__(self, name):
        self.username = name


name = raw_input('Please enter your name: ')
print 'Connecting...'

reactor.connectTCP('localhost', 8007, TTTClientFactory(name))

reactor.run()

我尽量把它写得简单易懂,但要实现聊天功能,我需要一些代码来从 stdin 读取数据,而不让反应器(reactor)卡住。因为你提到你使用的是图形用户界面(GUI),而不是终端的标准输入输出,所以其实这样做要简单得多——只需要选择一个与你的GUI库兼容的反应器,然后使用你平常的GUI事件就可以了。

希望这对你有帮助……

撰写回答