python - Partial read from Socket.File.Read -
im coding python script connects remote server, , parses returned response. odd reason, 9 out of 10 times, once header read, script continues , returns before getting body of response. im no expert @ python, im code correct on python side of things. here code:
class miniclient: "client support class simple internet protocols." def __init__(self, host, port): "connect internet server." self.sock = socket.socket(socket.af_inet, socket.sock_stream) self.sock.settimeout(30) try: self.sock.connect((host, port)) self.file = self.sock.makefile("rb") except socket.error, e: #if e[0] == 111: # print "connection refused server %s on port %d" % (host,port) raise def writeline(self, line): "send line server." try: # updated sendall resolve partial data transfer errors self.sock.sendall(line + crlf) # unbuffered write except socket.error, e: if e[0] == 32 : #broken pipe self.sock.close() # mutual close self.sock = none raise e except socket.timeout: self.sock.close() # mutual close self.sock = none raise def readline(self): "read line server. strip trailing cr and/or lf." s = self.file.readline() if not s: raise eoferror if s[-2:] == crlf: s = s[:-2] elif s[-1:] in crlf: s = s[:-1] return s def read(self, maxbytes = none): "read data server." if maxbytes none: return self.file.read() else: return self.file.read(maxbytes) def shutdown(self): if self.sock: self.sock.shutdown(1) def close(self): if self.sock: self.sock.close() self.sock = none
i use readline() method read through headers until reach empty line (delimiter between headers , body). there, objects call "read()" method read body. stated before, 9 of 10 times, read returns nothing, or partial data.
example use:
try: http = miniclient(host, port) except exception, e: if e[0] == 111: print "connection refused server %s on port %d" % (host,port) raise http.writeline("get %s http/1.1" % str(document)) http.writeline("host: %s" % host) http.writeline("connection: close") # not keep-alive http.writeline("") http.shutdown() # nice, tell http server we're done sending request # determine status statuscode = 0 status = string.split(http.readline()) if status[0] != "http/1.1": print "miniclient: unknown status response (%s)" % str(status[0]) try: statuscode = string.atoi(status[1]) except valueerror: print "miniclient: non-numeric status code (%s)" % str(status[1]) #extract headers headers = [] while 1: line = http.readline() if not line: break headers.append(line) http.close() # done #check got valid http response if statuscode == 200: return http.read() else: return "e\nh\terr\nd\thttp error %s \"%s\"\n$\terr\t$" % (str(statuscode), str(status[2]))
incorrect answer removed, not yet deleted (so comments can live while.)
Comments
Post a Comment