Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/279.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 尝试从低级套接字服务器发送HTTP响应_Python_Sockets_Http_Python Sockets - Fatal编程技术网

Python 尝试从低级套接字服务器发送HTTP响应

Python 尝试从低级套接字服务器发送HTTP响应,python,sockets,http,python-sockets,Python,Sockets,Http,Python Sockets,这是我的代码: # 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=u

这是我的代码:

# 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()
我做错了什么

注意:

完整的代码片段如下所示:

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()
导入套接字
#创建套接字对象并设置协议
s=插座。插座(
socket.AF_INET、socket.SOCK_STREAM)
#获取本地计算机的名称
host=socket.gethostname()
端口=80
#束缚
s、 绑定((主机、端口))
#听录音并设置待办事项(?)
s、 听(5)
#进程连接
打印('侦听端口',端口)
尽管如此:
c、 addr=s.accept()
打印(“从中获取连接”,地址)
msg=“”
响应\u头={
“内容类型”:“文本/html;编码=utf8”,
“内容长度”:len(msg.encode(encoding=“utf-8”),
“连接”:“关闭”,
}
响应\u头\u原始=“”。连接(“%s:%s\n”%(k,v)响应\u头.items()中的k,v)
response_proto='HTTP/1.1'
响应_状态='200'
响应_状态_文本='OK'#这可能是随机的
#发送所有这些东西
r=“%s%s%s%”(响应\u协议、响应\u状态、响应\u状态\u文本)
c、 发送(r.encode(encoding=“utf-8”))
c、 发送(响应\u头\u原始编码(encoding=“utf-8”))
c、 发送('\n'.encode(encoding=“utf-8”)#以将标题与正文分开
c、 发送(消息编码(encoding=“utf-8”))
c、 关闭()

问题在于HTTP头需要用
\r\n
行分隔,而不仅仅是
\n
。见和

如果你改变这一点,它将解决问题

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()
导入套接字
#创建套接字对象并设置协议
s=插座。插座(
socket.AF_INET、socket.SOCK_STREAM)
#获取本地计算机的名称
host=“127.0.0.1”
端口=8081
#束缚
s、 绑定((主机、端口))
#听录音并设置待办事项(?)
s、 听(5)
#进程连接
打印('侦听端口',端口)
尽管如此:
c、 addr=s.accept()
打印(“从中获取连接”,地址)
msg=“这是一个测试这里有更多内容

” 响应\u头={ “内容类型”:“文本/html;编码=utf8”, “内容长度”:len(msg), “连接”:“关闭”, } 响应\u头\u原始=“”.join(“%s:%s\r\n”%”(k,v)表示响应\u头.items()中的k,v) response_proto='HTTP/1.1' 响应_状态='200' 响应_状态_文本='OK'#这可能是随机的 #发送所有这些东西 r='%s%s%s\r\n'(响应\u协议、响应\u状态、响应\u状态\u文本) c、 发送(r) c、 发送(响应\u头\u原始) c、 发送('\r\n')#以将标题与正文分开 c、 发送(消息编码(encoding=“utf-8”)) c、 关闭()
根据
ERR\u CONNECTION\u RESET
错误,tcp套接字可能无法成功侦听端口

我在代码中将端口更改为8080,并在输出中编写一个
helloworld
,从而获得正确的HTML页面

如果要成功侦听80端口,必须使用root用户权限运行python脚本:

`sudo python server.py'


这是因为80端口是受系统限制的端口:。

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


我猜是因为服务器不读取客户机请求,而是简单地发送一些数据并关闭连接,而来自客户机的请求仍然在套接字缓冲区中,所以连接被重置。这是一个典型的错误,在和已经被询问和回答。

您是否使用了Chrome Developer工具或类似工具进行调查?如果它没有侦听
bind将失败,客户端也将被拒绝连接,或者最终超时。但不是重置。这表明它在一个点上连接了。只需添加到@drew010,我就能够通过命令行访问运行在端口80上的服务器。因此,该端口上的连接不是问题。我的理解是CRLF
('\r\n')
是windows特定的格式。这会在Unix系统上工作吗?还有。。。这个解决方案不起作用。我能够接收连接,但无法向浏览器发送响应。是的,HTTP将CRLF用作行尾标记(请参阅)。当我运行你的代码时,我会重置连接。当我更改为在每个标题行之间使用
\r\n
时,它可以工作。用完整代码编辑答案。这些链接都没有详细说明如何实际解决问题。@dopatraman:它们都说明问题在于您没有读取客户端的请求,而只是发送响应并用未读数据关闭套接字。解决方案显然是从客户机实际读取请求。难道你不明白这种相关性,或者你不知道如何阅读请求吗?
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()