我刚刚开始使用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, "..."
我的问题与handle_accept
类的HTTPServer
方法有关。如果每次请求进入时,HTTPChannel
对象都被初始化,那么在这种设置中创建呼叫和响应是不是不可能?我在想可以在通道对象中为_hastype
和_hasfile
设置标志,但由于每个连接都接受了它,因此每个单独的请求都会忘记对象的状态。我意识到这个设置应该是一个基本的HTTPServer,但我的问题是,我怎么能编辑它来设置像我所描述的那样?服务器对象是否需要继承asynchat本身并完全放弃调度程序?通道对象必须具有一些状态才能知道文件类型已经被发送,然后请求文件的二进制文件。我非常想知道这可能是最干净的实现方式。
非常感谢 - 我对插座很新。如果我不清楚,请告诉我。
答案 0 :(得分:1)
通常,连接在最初创建后将保持打开状态,因此来自同一客户端的通信的所有部分都转到相同的HTTPChannel
对象 - accept
仅在新连接时被调用创建