Seite 1 von 1

Socket - recv

Verfasst: Dienstag 18. November 2003, 16:52
von rayo
hi

self.conn.recv(1024)

Hier liest er ja vom Socket 1024 Zeichen ein, doch wenn nur 150 Zeichen kommen hört er nicht auf

Wollte einen kleinen Webserver selber schreiben mit Sockets, also einen Http-request bekommt er

wie mach ich das richtig? (lesen von einem socket)

gruss

*edit*
ups würde wohl in den netzwerk bereich fallen, sorry

Verfasst: Dienstag 18. November 2003, 21:07
von XT@ngel
Ich hab wie ich mit Python angefangen habe auch einen kleinen Server geschrieben:

Code: Alles auswählen

import socket
import string
import thread
import time

class request_handler:
	def __init__(self, client_data):
		#print "ID: " + `thread.get_ident()`
		
		#Runtime
		self.start_time = time.time()
		
		
		self.STATUS_HEADER = {}
		self.STATUS_HEADER["200"] = "HTTP/1.1 200 OK \nServer: PyServer v1.0\n"
		self.STATUS_HEADER["404"] = "HTTP/1.1 404 NOT FOUND\nServer: PyServer v1.0\n"
		self.STATUS_HEADER["501"] = "HTTP/1.1 501 NOT IMPLEMENTED \nServer: PyServer v1.0\n"
		
		#self.CONNECTION = {}
		#self.CONNECTION["close"] = "Connection: close\n"
		#self.CONNECTION["keep"] = "Connection: Keep-Alive\n"
		
		self.CONTENT_TYPE = {}
		self.CONTENT_TYPE["html"]  = "Content-Type: text/html\n\n"
		self.CONTENT_TYPE["plain"] = "Content-Type: text/plain\n\n"
		self.CONTENT_TYPE["jpeg"]  = "Content-Type: image/jpeg\n\n"
		self.CONTENT_TYPE["jpg"]   = "Content-Type: image/jpeg\n\n"
		self.CONTENT_TYPE["png"]   = "Content-Type: image/png\n\n"
		self.CONTENT_TYPE["gif"]   = "Content-Type: image/gif\n\n"
		
		self.client_data = client_data
		self.getHeader(self.client_data)
		self.sendData()
	
	
	def closeCon(self):
		self.client_data[0].close()
	
	
	def destroy(self):
		self.closeCon()
		self.fp.close()
		#Runtime
		self.end_time = time.time()		    
		print "\tRuntime [" + `self.end_time-self.start_time` + "] sec."
		#---------------------------------------------------------------------------------------------------------
		thread.exit()
	
	
	def getHeader(self, client):
		reuqest_header = client[0].recv(1024)
		if reuqest_header == "":
			self.destroy()
		#print reuqest_header
		reuqest_header = string.split(reuqest_header, '\n')
		self.r_header = {}
		for i in reuqest_header[1:]:
			info = string.split(i, ':' , 1) #Nur einmal trennen! :-)
			if len(info) >= 2:
				self.r_header[info[0]] = string.strip(info[1])
		reuqest_header_first_line = string.split(reuqest_header[0])
		self.r_header["Method"] = reuqest_header_first_line[0]
		self.r_header["File"] = reuqest_header_first_line[1]
		self.r_header["Protocol"] = reuqest_header_first_line[2]
		
		
		#return :::
		#print r_header["Method"] #print r_header["File"] #print r_header["Protocol"] #print r_header["Host"] 
		#print r_header["User-Agent"]  #print r_header["Accept"] #print r_header["Accept-Language"]
		#print r_header["Accept-Encoding"] #print r_header["Accept-Charset"] 
		#print self.r_header
		#print r_header["Connection"]#print r_header["Referer"]
	
	
	def generateHeader(self, status, type, info=""):
			self.header = self.STATUS_HEADER[status] +  self.CONTENT_TYPE[type] + info
			#print self.header
	
	def openFile(self):
		#--- CONTENT-TYPE FESTELLEN ANHAND DER ENDUNG ----
		pos = string.rfind(self.r_header["File"], ".")
		#print pos
		if pos == -1:
			type = "NONE"
			print "I CLOSE CONNECTION BY ERROR MIME-TYPE"
		else:
			type = self.r_header["File"][pos+1:]
		#-------------------------------------------------------------------------------------------
		file = root_dir + self.r_header["File"]
		type = string.lower(type)
		try:
		    self.fp = open(file,'rb')
		    self.generateHeader("200", type) 
		    return 1
		except IOError:
		    if self.CONTENT_TYPE.has_key(type) == 0:
		       print type
		       self.generateHeader("501", "html", "<html><head><title>501 Error</title></head><body><h1>501 NOT IMPLEMENTED </h1></body></html>")
		    else:
		       self.generateHeader("404", "html", "<html><head><title>404 Error</title></head><body><h1>404 File Not Found</h1></body></html>")
		    return 0
	
	
	def sendData(self):
		status = self.openFile()
		#print "Sende HEADER: " +  self.header
		#print "Oeffne der File: " + `status`
		if status == 0:
			self.client_data[0].send(self.header)
			self.closeCon()
		elif status == 1:
			self.client_data[0].send(self.header)
			while 1:
				self.buffer= self.fp.readline()
				if self.buffer == "":
					break
				self.client_data[0].send(self.buffer)
			self.destroy()
	

root_dir = "/home/andreas/backup/server/root"

server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server.bind(("",8000))
server.listen(1)

#hauptschleife
while 1:
	conn,addr = server.accept()
	if conn and addr:
		client_data = (conn,addr)
		#print "______________________________________________________________"
		thread.start_new_thread(request_handler,(client_data,))
		print `addr[0]` + " Connect"


Und bei mir läuft

Code: Alles auswählen

reuqest_header = client[0].recv(1024)
einwandfrei

MfG
Andreas

Verfasst: Dienstag 18. November 2003, 21:49
von rayo
mm hab jetzt an meinem code ein wenig gebastelt

jetzt gehts auf einmal :D
aber danke für dein beispiel, werde da falls nötig nachgucken

gruss

Verfasst: Dienstag 18. November 2003, 23:20
von rayo
so jetzt gehts schon recht gut, nur spinnen die browser mit dem css

bei opera gehts
bei mozilla lädt er das css nicht (per direkt aufruft http://server/style.css zeigt ers an)
bei internet explorer lädt er das css auch nicht (per direkt aufruft http://server/style.css will er es downloaden aber bricht ab weil das cssfile nicht verfügbar sei)
html files gehen auf allen browsern

hier ein kleiner codeausschnitt:

Code: Alles auswählen

header = self.conn.recv(102400)
... (header parsing)
if fileext == 'css':
  self.sendHeader(['HTTP/1.1 400 OK','Content-Type: text/css'])
  self.sendfile(fullfilename,False)
elif fileext == 'html':
  self.sendHeader(['HTTP/1.1 400 OK','Content-Type: text/html'])
  self.sendfile(fullfilename)
self.conn.close()
in sendfile und sendheader werden nur self.conn.send(daten) aufgerufen

hat einer ne ahnung warum?

gruss[/code]

Verfasst: Mittwoch 19. November 2003, 15:08
von XT@ngel
Wie bindest du die css ein ?:

Code: Alles auswählen

<link rel="stylesheet" type="text/css" href="style/style.css">
Das funktioniert bei mir sowohl mit Opera 7 und Mozilla Firebird :)


Und wieso sendest du einen 400er ?

Code: Alles auswählen

self.sendHeader(['HTTP/1.1 400 OK','Content-Type: text/css']) 
->400 BAD REQUEST
Wenn die Datei gefunden wird musst du einen 200er Status mitschicken.
Aber rätselhaft ist bei dir, das html Dateien bei jedem Browser gehen.

hab mich schon lange nicht mehr damit beschäftigt aber schau mal hier vorbei:
http://www.bolege.de/http-status-codes/
http://www.faqs.org/rfcs/rfc2068.html

MfG
Andreas

Verfasst: Mittwoch 19. November 2003, 15:22
von rayo
uups dann hab ich das verwechselt :D

peinlicher fehler

so gehts, nur komisch das opera gar nicht darauf achtet

so mehr braucht der webserver nicht nicht zu unterstützen, ist eine weboberfläche für mein aktuelles projekt

gruss