[Tutor] Sockets, again

Jonathan Hayward http://JonathansCorner.com jonathan.hayward at pobox.com
Wed Aug 6 23:48:14 EDT 2003


I've got past the problem I'd noticed earlier (source: I opened the 
output socket-file "r" and the input socket-file "wb", and that's why I 
had the bad file descriptor. Oof.).

I want the client to encode its environmental and CGI data, feed a blank 
line or other end-of-input indicator, and get a webpage back. My current 
problem is that the script hangs, possibly stuck in an infinite loop, or 
more probably deadlocked on input. Or that's my best guess; I hope I'm 
missing something very simple again. The server seems to be giving the 
client a steady stream of either newlines or nulls.

So the client opens up with a query like:

    environment_variable REMOTE_HOST
    [Pickling of "127.0.0.1"]
    cgi page_mode
    [Pickling of a page mode]
    @@END_OF_QUERY@@

Then the server would think a bit and send back a pickled webpage. 
(Using cPickle is overkill now, but I want to leave a couple of doors 
open to things that might be useful later.)

Any help would be appreciated. This is the interface code I have now for 
the client:

    def get_page_from_oracle(self):
        self.check_and_start_oracle()
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        try:
            sock.connect((configuration.get_search_server_ip(), \
              configuration.get_search_server_port()))
            sockIn = sock.makefile("rb")
            sockOut = sock.makefile("wb")
            for current_environment_key in os.environ.keys():
                sockOut.write("environmental_variable " + \
                  current_environment_key + "\r\n")
                cPickle.dump(os.environ[current_environment_key], sockOut)
            for cgi_key in cgi.FieldStorage().keys():
                sockOut.write("cgi_value " + cgi_key + "\r\n")
                cPickle.dump(cgi.FieldStorage[cgi_key])
            sockOut.write(configuration.get_query_terminator() + "\r\n")
            sockOut.write("\r\n")
            #result = cPickle.load(sockIn)
            result = sockIn.readline()
            sock.close()
            sockIn.close()
            sockOut.close()
            #return "Content-type: text/html\n\nget_page_from_oracle"
            return result
        except socket.error, e:
            return "Content-type: text/html\n\n<h1>There was an error 
loading this page.</h1>" + str(e)

And the server:

    def handle_oracle_query(self, sock, address):
        """Reads a CGI or other header variable alone on a line, format like
            cgi_value <HTML form element name>
            environmental_variable REMOTE_ADDR
        and then a pickled value. There is exactly one space between the two
        elements, and neither element may contain a space"""
        sockIn = sock.makefile("rb")
        sockOut = sock.makefile("wb")
        line = sockIn.readline()
        should_continue = 1
        while should_continue:
            if not self.get_thread_specific_storage().has_key("cgi"):
                self.get_thread_specific_storage()["cgi"] = None
            if not self.get_thread_specific_storage().has_key( \
              "environmental_variables"):
                
self.get_thread_specific_storage()["environmental_variables"] \
                  = None
            if self.get_thread_specific_storage()["cgi"] == None:
                self.get_thread_specific_storage()["cgi"] = {}
            if 
self.get_thread_specific_storage()["environmental_variables"] \
              == None:
                
self.get_thread_specific_storage()["environmental_variables"] \
                  = {}
            cgi = self.get_thread_specific_storage()["cgi"]
            environmental_variables = \
              self.get_thread_specific_storage()["environmental_variables"]
            line = re.sub("[\r\n]+", "", line)
            query_line = re.split("\s+", line)
            if len(query_line) == 2:
                input_type = query_line[0]
                input_name = query_line[1]
                if input_type == "cgi_value":
                    cgi[input_name] = cPickle.load(sockIn)
                elif input_type == "environmental_variables":
                    environmental_variables[input_name] = 
cPickle.load(sockIn)
            else:
                should_continue = 0
            line = sockIn.readline()
        generate_output()
        print_output(sockOut)
        sockOut.write("\r\n")
        sock.close()
        sockIn.close()
        sockOut.close()

-- 
++ Jonathan Hayward, jonathan.hayward at pobox.com
** To see an award-winning website with stories, essays, artwork,
** games, and a four-dimensional maze, why not visit my home page?
** All of this is waiting for you at http://JonathansCorner.com





More information about the Tutor mailing list