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()

当我在浏览器上访问我的本地 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()
4

3 回答 3

1

问题是 HTTP 标头需要由\r\nnot just分隔行\n。请参阅RFC 1945 - HTTP/1.0 Sec 2.2RFC 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()
于 2016-03-21T03:13:59.493 回答
0

根据ERR_CONNECTION_RESET错误,您的 tcp 套接字可能没有成功侦听端口。

我在您的代码中将端口更改为 8080 并Hello world在输出中写入 a,从而获得正确的 HTML 页面。

如果你想成功监听 80 端口,你必须使用 root 用户权限来运行你的 python 脚本:

`sudo python server.py'

那是因为 80 端口是系统限制端口:为什么前 1024 个端口仅限于 root 用户?.

于 2016-03-21T03:22:46.113 回答
-1

我假设您将能够侦听端口 80 并接受连接,否则您的服务器应该尽早抛出异常。

我的猜测是您重置了连接,因为您的服务器没有读取客户端请求,而是简单地发送一些数据并关闭连接 - 来自客户端的请求仍在套接字缓冲区中。这是一个典型的错误,已经在Perl 中询问和回答:使用简单 HTTP 服务器重置连接HTTP 服务器未向 WGET、Firefox 发送完整文件。对等方重置连接?当尝试连接到本地主机套接字服务器和超简单 HTTP 套接字服务器时,Web 浏览器上的“连接已重置”,用PHP 编写,行为异常使用 fork 和 dup 的简单 http 通用服务器

于 2016-03-21T06:12:02.890 回答