2011-07-18 58 views
0

我剛開始使用python套接字網絡的基礎知識。作爲一個理解的練習,我一直在試圖散列一個基本的服務器,它會詢問它的客戶端是否是文件類型,並且在收到一串擴展名後,詢問實際的文件。我在網上發現了很多使用asyncore庫的教程,特別是asynchat來設置這種調用和響應功能。python 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,但我的問題是,我怎麼能編輯它來設置我所描述的東西?服務器對象是否需要繼承asynchat本身並完全放棄調度器?通道對象必須有一些狀態才能知道文件類型已經發送,然後請求文件的二進制文件。我非常好奇,想知道這個最簡潔的實現可能是什麼樣子。

非常感謝 - 我對套接字很陌生。如果我不清楚,請告訴我。

回答

1

正常情況下,連接在最初創建後會保持打開狀態,因此來自同一客戶端的通信的所有部分都轉到同一個HTTPChannel對象 - 只有在創建新連接時纔會調用該對象 - accept

+0

那麼接受不會運行在兩者之間的每一次傳輸?我似乎誤解了這個方法。什麼樣的條件會結束連接? – DeaconDesperado

+0

我想我發現我做錯了什麼......我有客戶端在每次傳輸後關閉套接字上的連接。我誤解了這意味着只是結束「討論」的一部分而不是全部。感謝您的指導! – DeaconDesperado