这是我的代码:
# Process connections
print('Listening on port', port)
while True:
c, addr = s.accept()
print("Got connection from", addr)
msg = "<html></html>"
response_headers = {
'Content-Type': 'text/html; encoding=utf8',
'Content-Length': len(msg.encode(encoding="utf-8")),
'Connection': 'close',
}
response_headers_raw = ''.join('%s: %s\n' % (k, v) for k, v in response_headers.items())
response_proto = 'HTTP/1.1'
response_status = '200'
response_status_text = 'OK' # this can be random
# sending all this stuff
r = '%s %s %s' % (response_proto, response_status, response_status_text)
c.send(r.encode(encoding="utf-8"))
c.send(response_headers_raw.encode(encoding="utf-8"))
c.send('\n'.encode(encoding="utf-8")) # to separate headers from body
c.send(msg.encode(encoding="utf-8"))
c.close()
当我在浏览器上访问我的本地IP时,会出现一个错误页面
ERR_CONNECTION_RESET
我做错了什么?
注意:
完整的代码段在这里:
import socket
# Create socket object and set protocol
s = socket.socket(
socket.AF_INET, socket.SOCK_STREAM)
# Get name of local machine
host = socket.gethostname()
port = 80
# Bind
s.bind((host, port))
# Listen and set backlog (?)
s.listen(5)
# Process connections
print('Listening on port', port)
while True:
c, addr = s.accept()
print("Got connection from", addr)
msg = "<html></html>"
response_headers = {
'Content-Type': 'text/html; encoding=utf8',
'Content-Length': len(msg.encode(encoding="utf-8")),
'Connection': 'close',
}
response_headers_raw = ''.join('%s: %s\n' % (k, v) for k, v in response_headers.items())
response_proto = 'HTTP/1.1'
response_status = '200'
response_status_text = 'OK' # this can be random
# sending all this stuff
r = '%s %s %s' % (response_proto, response_status, response_status_text)
c.send(r.encode(encoding="utf-8"))
c.send(response_headers_raw.encode(encoding="utf-8"))
c.send('\n'.encode(encoding="utf-8")) # to separate headers from body
c.send(msg.encode(encoding="utf-8"))
c.close()
答案 0 :(得分:0)
问题是HTTP标头需要由\r\n
分隔,而不仅仅是\n
。请参阅RFC 1945 - HTTP/1.0 Sec 2.2和RFC 7230 - HTTP/1.1 Syntax and Routing Sec 3。
如果你改变它,它将解决问题。
import socket
# Create socket object and set protocol
s = socket.socket(
socket.AF_INET, socket.SOCK_STREAM)
# Get name of local machine
host = "127.0.0.1"
port = 8081
# Bind
s.bind((host, port))
# Listen and set backlog (?)
s.listen(5)
# Process connections
print('Listening on port', port)
while True:
c, addr = s.accept()
print("Got connection from", addr)
msg = "<html><body><h1>This is a test</h1><p>More content here</p></body></html>"
response_headers = {
'Content-Type': 'text/html; encoding=utf8',
'Content-Length': len(msg),
'Connection': 'close',
}
response_headers_raw = ''.join('%s: %s\r\n' % (k, v) for k, v in response_headers.items())
response_proto = 'HTTP/1.1'
response_status = '200'
response_status_text = 'OK' # this can be random
# sending all this stuff
r = '%s %s %s\r\n' % (response_proto, response_status, response_status_text)
c.send(r)
c.send(response_headers_raw)
c.send('\r\n') # to separate headers from body
c.send(msg.encode(encoding="utf-8"))
c.close()
答案 1 :(得分:0)
根据ERR_CONNECTION_RESET
错误,您的tcp套接字可能无法成功收听该端口。
我在您的代码中将端口更改为8080,并在输出中写入Hello world
,从而获得正确的HTML页面。
如果要成功侦听80端口,则必须使用root用户权限来运行python脚本:
`sudo python server.py&#39;
这是因为80端口是系统受限端口:Why are the first 1024 ports restricted to the root user only?。
答案 2 :(得分:-1)
我假设您将能够侦听端口80并接受连接,否则您的服务器应该提前抛出异常。
我的猜测是你重置连接,因为你的服务器没有读取客户端请求,而只是发送一些数据并关闭连接 - 来自客户端的请求仍然在套接字缓冲区中。这是一个典型的错误,已在Perl: Connection reset with simple HTTP server和HTTP Server Not Sending Complete File To WGET, Firefox. Connection reset by peer?以及"The connection was reset" on web browsers when trying to connect to a localhost socket server和Ultra simple HTTP socket server, written in PHP, behaving unexpectedly以及Simple http generic server using fork and dup处提出并回答。