[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