python 异步状态
我刚刚开始学习 python 套接字网络的基础知识。作为理解练习,我一直在尝试构建一个基本服务器,该服务器将向客户端询问文件类型,并在收到扩展名字符串后询问实际文件。我在网上找到了许多使用 asyncore 库的教程,特别是 asynchat 来设置这种调用和响应功能。
我一直在关注的最基本的可以在这里找到(我已经复制了它)
http://effbot .org/librarybook/asynchat.htm
import asyncore, asynchat
import os, socket, string
PORT = 8000
class HTTPChannel(asynchat.async_chat):
def __init__(self, server, sock, addr):
asynchat.async_chat.__init__(self, sock)
self.set_terminator("\r\n")
self.request = None
self.data = ""
self.shutdown = 0
def collect_incoming_data(self, data):
self.data = self.data + data
def found_terminator(self):
if not self.request:
# got the request line
self.request = string.split(self.data, None, 2)
if len(self.request) != 3:
self.shutdown = 1
else:
self.push("HTTP/1.0 200 OK\r\n")
self.push("Content-type: text/html\r\n")
self.push("\r\n")
self.data = self.data + "\r\n"
self.set_terminator("\r\n\r\n") # look for end of headers
else:
# return payload.
self.push("<html><body><pre>\r\n")
self.push(self.data)
self.push("</pre></body></html>\r\n")
self.close_when_done()
class HTTPServer(asyncore.dispatcher):
def __init__(self, port):
asyncore.dispatcher.__init__(self)
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
self.bind(("", port))
self.listen(5)
def handle_accept(self):
conn, addr = self.accept()
HTTPChannel(self, conn, addr)
#
# try it out
s = HTTPServer(PORT)
print "serving at port", PORT, "..."
我的问题与 HTTPServer
类的 handle_accept
方法有关。如果每次收到请求时,HTTPChannel
对象都会被初始化,那么在这种设置中不是不可能创建调用和响应吗?我认为可以在通道对象中为 _hastype
和 _hasfile
设置标志,但由于接受会为每个单独的连接初始化它,因此每个单独的请求都会忘记该对象的状态。我意识到这个设置应该是一个基本的 HTTPServer,但我的问题是,我如何编辑它来设置像我所描述的那样的东西?服务器对象是否需要继承异步本身并完全放弃调度程序?通道对象必须具有某种状态才能知道文件类型已被发送,然后请求文件的二进制文件。我很好奇最干净的实现可能是什么样子。
非常感谢 - 我对套接字很陌生。如果我没有说清楚,请告诉我。
I've just started working with the basics of python socket networking. As an exercise in understanding, I've been trying to hash out a basic server that will ask it's client for a file type, and upon receiving a string of the extension, ask for the actual file. I've found numerous tutorials online that use the asyncore library, specifically asynchat to setup this kind of call and response functionality.
The most basic one I've been following can be found here (I've copied it)
http://effbot.org/librarybook/asynchat.htm
import asyncore, asynchat
import os, socket, string
PORT = 8000
class HTTPChannel(asynchat.async_chat):
def __init__(self, server, sock, addr):
asynchat.async_chat.__init__(self, sock)
self.set_terminator("\r\n")
self.request = None
self.data = ""
self.shutdown = 0
def collect_incoming_data(self, data):
self.data = self.data + data
def found_terminator(self):
if not self.request:
# got the request line
self.request = string.split(self.data, None, 2)
if len(self.request) != 3:
self.shutdown = 1
else:
self.push("HTTP/1.0 200 OK\r\n")
self.push("Content-type: text/html\r\n")
self.push("\r\n")
self.data = self.data + "\r\n"
self.set_terminator("\r\n\r\n") # look for end of headers
else:
# return payload.
self.push("<html><body><pre>\r\n")
self.push(self.data)
self.push("</pre></body></html>\r\n")
self.close_when_done()
class HTTPServer(asyncore.dispatcher):
def __init__(self, port):
asyncore.dispatcher.__init__(self)
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
self.bind(("", port))
self.listen(5)
def handle_accept(self):
conn, addr = self.accept()
HTTPChannel(self, conn, addr)
#
# try it out
s = HTTPServer(PORT)
print "serving at port", PORT, "..."
My question has to do with the handle_accept
method of the HTTPServer
class. If every time a request comes in, the HTTPChannel
object is initialized, wouldn't it be impossible in this kind of setup to create a call and response? I was thinking one could set flags for _hastype
and _hasfile
in the channel object, but since the accept inits it for each individual connection, the object's state is forgotten with every inidividual request. I realize this setup is supposed to be a basic HTTPServer, but my question is, how could I edit it to setup something like what I've described? Would the server object need to inherit asynchat itself and forego dispatcher completely? The channel object would have to have some state to know that the filetype has already been sent, and then ask for the binary of the file instead. I'm very curious to know what the cleanest possible implementation of this might look like.
Thanks a ton - I'm very new to sockets. Please let me know if I haven't been clear.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
通常,连接在最初创建后会保持打开状态,因此来自同一客户端的通信的所有部分都会转到同一个
HTTPChannel
对象 -accept
仅在以下情况下调用:新连接已创建。Normally the connection would be kept open after it's initially created, so all the parts of the communication from the same client go to the same
HTTPChannel
object -accept
is only called when a new connection is created.