gpt4 book ai didi

python 网络: asynchat handshake

转载 作者:行者123 更新时间:2023-11-30 23:47:26 28 4
gpt4 key购买 nike

我正在使用 python asynchat 来实现网络协议(protocol)。在连接时,我需要发送命令,服务器通过 session 进行应答。

我的主要问题是我需要等待直到收到 session 响应。但不知道如何实现这一点。我应该使用 socket.recv 进行连接设置吗?是个好主意吗?

最佳答案

当使用异步技术编写网络应用程序时,您可以通过在某处记录状态来等待,然后让主循环继续。在将来的某个时间,您正在等待的数据将变得可用,主循环将通知您这一事实,并且您可以将新数据与记录的状态结合起来以完成您正在处理的任何任务。根据具体任务的不同,您可能需要多次执行此循环才能真正完成任务。

无论您使用什么异步系统,这些想法基本上都是相同的。然而,Twisteda vastly superior systemasynchat ,所以我不会尝试解释任何异步聊天细节。相反,这里有一个使用 Twisted 完成您所询问的事情的示例:

from twisted.internet.defer import Deferred
from twisted.internet.protocol import Protocol, Factory
from twisted.internet.endpoints import TCP4ClientEndpoint
from twisted.internet import reactor

# Stream-oriented connections like TCP are handled by an instance
# of a Protocol subclass
class SomeKindOfClient(Protocol):

# When a new connection is established, the first thing that
# happens is this method is called.
def connectionMade(self):
# self.transport is set by the superclass, and lets us
# send data over the connection
self.transport.write("GREETING")

# a Deferred is a generic, composable API for specifying
# callbacks
self.greetingComplete = Deferred()

# Here's some local state
self._buffer = ""

# Whenever bytes arrive on the TCP connection, they're passed
# to this method
def dataReceived(self, bytes):

# Incorportate the network event data into our local state.
# This kind of buffering is always necessary with TCP, because
# there's no guarantees about how many bytes will be delivered
# at once (except that it will be at least 1), regardless of
# the size of the send() the peer did.
self._buffer += bytes

# Figure out if we're done - let's say the server response is 32
# bytes of something
if len(self._buffer) >= 32:
# Deliver it to whomever is waiting, by way of the Deferred
# object
greeting, self._buffer = self._buffer[:32], self._buffer[32:]
complete = self.greetingComplete
self.greetingComplete = None
complete.callback(greeting)

# Otherwise we'll keep waiting until dataReceived is called again
# and we have enough bytes.


# One of the normal ways to create a new client connection
f = Factory()
f.protocol = SomeKindOfClient
e = TCP4ClientEndpoint(reactor, "somehost", 1234)

# Connect returns one of those Deferreds - letting us specify a function
# to call when the connection is established. The implementation of
# connect is also doing basically the same kind of thing as you're asking
# about.
d = e.connect(f)

# Execution continues to this point before the connection has been
# established. Define a function to use as a callback when the connection
# does get established.
def connected(proto):
# proto is an instance of SomeKindOfClient. It has the
# greetingComplete attribute, which we'll attach a callback to so we
# can "wait" for the greeting to be complete.
d = proto.greetingComplete

def gotGreeting(greeting):
# Note that this is really the core of the answer. This function
# is called *only* once the protocol has decided it has received
# some necessary data from the server. If you were waiting for a
# session identifier of some sort, this is where you might get it
# and be able to proceed with the remainder of your application
# logic.
print "Greeting arrived", repr(greeting)

# addCallback is how you hook a callback up to a Deferred - now
# gotGreeting will be called when d "fires" - ie, when its callback
# method is invoked by the dataReceived implementation above.
d.addCallback(gotGreeting)

# And do the same kind of thing to the Deferred we got from
# TCP4ClientEndpoint.connect
d.addCallback(connected)

# Start the main loop so network events can be processed
reactor.run()

要了解其行为方式,您可以启动一个简单的服务器(例如 nc -l 1234)并将客户端指向它。您将看到问候语到达,并且您可以发回一些字节。一旦您发回 30,客户端就会打印它们(然后无限期地等待,因为我在该协议(protocol)中没有实现进一步的逻辑)。

关于 python 网络: asynchat handshake,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8394790/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com