使用套接字API编写一个基本的HTTP服务器
我有以下代码在我的server.py文件中。它正在等待从客户端接收数据。另外我不能使用任何的http库。只有插座库:使用套接字API编写一个基本的HTTP服务器
def handle_client(conn, addr):
print ('New client from', addr)
x = []
try:
while True:
data = conn.recv(1024)
decoded_data = data.decode('utf-8')
# if "GET/" in data.decode('utf-8'):
# handle_client_get(conn)
# else:
if data:
print(data)
x.append(decoded_data)
else:
print(x)
break
finally:
print("in close now")
conn.close()
我遇到的问题是,我只能达到print(x)
声明一次我手动CTRL + C
关闭客户端。否则它不会打印。
为什么是这种情况。
ANSWER
您需要确认发送到这样发送的数据已经正确接收客户端。
这将终止连接,而不是等待超时。
这是因为客户端发送:Expect: 100-continue
你需要发送一个确认返回给客户端
编辑:
既然你提到这是一个HTTP服务器,并且是只用做socket
库,我建议你在此阶段从程序中删除某些复杂的元素,例如删除while
块,直到解决此问题。
server.py
def handle_client(conn, addr):
print ('New client from', addr)
x = []
try:
data = conn.recv(1024)
decoded_data = data.decode('utf-8')
if data:
print(data)
x.append(decoded_data)
else:
print(x)
break
finally:
print("in close now")
conn.close()
原来的答案:
尝试在发送端发送一个额外\n
和使用flush
功能后发出的缓冲区内把所有剩余的数据如:
sender.py
def send_data(data,sock_obj,addr):
sock_obj.send(data+"\n")
sock_obj.flush()
我使用的卷曲,所以我不能添加这些细节,以客户正在发送 – user3450754
吗?我不需要while循环,虽然,这样我得到的所有数据从客户端发送? – user3450754
您需要实现协议,该协议将会告诉您需要读取多少数据。在HTTP的情况下,请求以CRLF定界标题开始,我们可以读取它以获取我们想要的信息。
w3.org
对http request protocol有很好的描述。它比我想在这里实现更复杂,但我已经包含了一个例子,通过读取套接字一个字符,并寻找一个空的\n
终止线拉入请求标题。通过一次读取一个字符,我不必实现我自己的行缓冲区。
第一行是请求方法,其余行是请求中包含的其他参数。例如,对于一个POST,将会有更多的数据仍然要从套接字中读取。
import re
def handle_client(conn, addr):
print ('New client from', addr)
header = []
line = []
try:
# read ascii http client header.
while True:
c = conn.recv(1)
# check for early termination
if not c:
return None
# check for end of request line
elif c == b"\n":
# make line a string to add to header
line = ''.join(line).decode('ascii').strip()
# are we at the empty line signalling end-of-header?
if not line:
break
header.append(line)
line = []
# filter out \r
elif c == b"\r":
continue
# request is first line of header
request_line = header.pop(0)
method, uri, http_version = re.split(r" +" request_line)
if method.upper() == "GET":
# this function needs more parameters... the uri to get and the protocol
# version to use.
handle_client_get(...)
finally:
print("in close now")
conn.close()
好的,客户端会发送一个发送一个包含一些ascii字符的文件的请求。我确实得到了所有的信息,但只要我得到所有信息,就不会关闭连接。就好像它正在等待更多的数据。这是我的问题。 – user3450754
头部可能会包含'Transfer-Encoding'来告诉你它是否是ascii或其他内容,以及'Content-Length'来告诉你要读取多少字节。但像所有事情一样,可能会有复杂性。阅读部分_4.4消息长度_ [这里](https://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.3)。 – tdelaney
这与'expect:100-continue'有关。我发现问题出在哪里 – user3450754
另一侧没有关闭插座。在接收通道被另一端关闭后,您只会收到一个空的recv。 – tdelaney
但是如果没有数据从客户端发送,我该怎么办? 你是说即使没有数据从客户端发送,只要有一个连接,我不能达到else语句? – user3450754
您需要定义您的协议才能获得更好的答案。是否有接收更多数据的预期时间表?为什么服务器在连接完成后保持连接状态?有些协议,例如telnet或ssh,可能没有数据的分钟或小时,但连接仍然有效,并且在没有数据的延长时间段之后可能有更多的数据。 – dsh