【问题标题】:How to send an HTTP Response for an incoming request using python sockets如何使用 python 套接字为传入请求发送 HTTP 响应
【发布时间】:2021-09-03 05:10:25
【问题描述】:

我有一个 Python 服务器编码为在 http://127.0.0.1:9999/ 上工作。服务器打印出传入的 http 请求。我还对在响应期间要发送的标头以及内容进行了编码。代码如下:

import socket
from time import sleep
c = None #Client socket1
addr = None #Client address1
    
server_socket1 = socket.socket() #by default it is SOCK_STREAM (TCP) and has porotocal AF_INET (IPv4) 

server_socket1.bind(('127.0.0.1',9999)) #server machine's ip and port on which it will send and recieve connections from

server_socket1.listen(2) #We will only accept two connections as of now , one for each client
print("Server started successfully!!!")
print("Waiting for connections...\n\n")

while (((c is None)and(addr is None))):
    if((c is None) and (addr is None)):
        c,addr = server_socket1.accept()
        print("User connected to client1 socket!!")
        c.send(bytes("Connected to the apps server!!!","utf-8"))
        print("Client connected ip address "+str(addr))
        

        
while True:
    msg = c.recv(4096)
    if(msg!=None):
            #print(msg)
            headers, sep, body = msg.partition(b'\r\n\r\n')
            headers = headers.decode('utf-8') 
            print(headers)

            html_body = "<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(html_body),
            '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.sendall(r.encode())
            c.sendall(response_headers_raw.encode())
            c.sendall(b'\r\n') # to separate headers from body
            c.send(html_body.encode(encoding="utf-8"))

            sleep(5)

代码运行没有编译错误,启动服务器并捕获我从预期浏览器发送的请求。但是,在发送响应时,套接字连接会关闭并出现错误,因为 [WinError 10053] 已建立的连接已被主机中的软件中止

从浏览器发送的请求:

终端中的输出:

浏览器显示的错误:

什么可能导致此错误?以前 python 在发送 response_headers_raw 变量时提示我该对象必须是字节类型而不是类型“str”的错误。因此,我使用 encode() 函数将其转换为字节类型对象,这导致我出现此错误。

任何解决方案将不胜感激!

~问候

【问题讨论】:

  • 首先,你为什么到处使用这么多括号? while (((c is None)and(addr is None)))
  • 推荐使用这个库,python-socketio.readthedocs.io/en/latest/…。无需重新发明轮子。
  • 有什么建议可以改进现有的代码库吗?我想在不使用任何框架或库的情况下开发服务器来实现和学习套接字编程概念。

标签: python python-3.x sockets client-server httpresponse


【解决方案1】:
    c,addr = server_socket1.accept()
    print("User connected to client1 socket!!")
    c.send(bytes("Connected to the apps server!!!","utf-8"))

您在连接后立即向客户端发送“已连接到应用服务器!!!”。客户端虽然期待 HTTP 响应。由于它获取您的非 HTTP 数据,因此客户端会关闭连接。稍后c.sendall 将写入被对等方关闭的套接字,导致“已建立的连接被中止”

除此之外...

msg = c.recv(4096)
if(msg!=None):
        #print(msg)
        headers, sep, body = msg.partition(b'\r\n\r\n')

您的期望似乎是c.recv 将在套接字关闭时返回None。这不是真的,它将返回''。这意味着即使在第一个错误被修复后,如果对等方在成功读取请求并发送响应后关闭了连接,您的代码也会再次遇到类似的问题。

【讨论】:

  • 非常感谢。我删除了那条线,它就像魅力一样! :)
猜你喜欢
  • 2013-05-14
  • 2015-12-26
  • 1970-01-01
  • 2011-03-03
  • 1970-01-01
  • 2012-04-24
  • 2012-02-09
  • 2022-11-15
  • 2013-09-29
相关资源
最近更新 更多