gpt4 book ai didi

python发送http响应

转载 作者:可可西里 更新时间:2023-11-01 15:30:15 27 4
gpt4 key购买 nike

我正在尝试编写一个非常 简单的 HTTP 服务器,它发送正在服务器端流式传输的视频。当客户端连接时,get_video 程序(虚构的)在另一个进程中启动,其标准输出通过管道传输给我们(假设 get_video 将视频发送/流式传输到标准输出)。我为此使用 subprocess.Popen()

import subprocess, socket

def send_video(sock, programme_id):
p = subprocess.Popen(["get_video","--pid",programme_id], stdout=subprocess.PIPE)
sock.send("HTTP/1.1 200 OK\nContent-type: application/octet-stream\n\n")
while True:
chunk = p.stdout.read(1024)
if chunk:
try:
sock.send(chunk)
except Exception:
pass
else:
break

def main():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('',8080))
s.listen(5)

while True:
client, address = s.accept()
data = client.recv(1024)
send_video(client, "123456")
client.close()

if __name__ == "__main__":
main()

这几乎行不通。如果我使用 wget <a href="http://localhost:8080/blah.mp4" rel="noreferrer noopener nofollow">http://localhost:8080/blah.mp4</a> 发出一个 HTTP 请求,整个过程都会按预期进行——视频将流式传输到客户端的套接字并附加到新文件 blah.mp4。

但是,如果我使用 <a href="http://localhost:8080/blah/mp4">download</a> 创建一个虚拟 HTML 页面,然后尝试在该链接上“将目标/链接另存为...”,则会调用 get_video 程序两次。第二次是视频实际发送到客户端套接字的时候。一定有某种缓冲在进行。

注意 try/except 中的 send_video() block 。之前我遇到了一个“破损的管道”错误(使用虚拟 HTML 页面方法),表明客户端的套接字没有被写入。我将 try/except 放在那里试图忽略它。

我很困惑。 HTTP 请求看起来一样,我不确定我的浏览器 (Firefox) 的不同之处导致了这种情况。

有什么想法吗?

编辑:

来自 wget 的 header :

GET /blah.mp4 HTTP/1.0
User-Agent: Wget/1.12 (linux-gnu)
Accept: */*
Host: 192.168.1.2:8080
Connection: Keep-Alive

来自 html 虚拟页面的标题:

GET /blah.mp4 HTTP/1.1
Host: 192.168.1.2:8080
User-Agent: Mozilla/5.0 (blah) Gecko/blah Firefox/3.6.16
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-gb,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 115
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache

python 服务器只报告了其中一个,但 Wireshark 报告了 2 个针对虚拟 html 链接方法的 GET 请求。我在这里看不到任何明显的东西......

最佳答案

我突然意识到,因为浏览器在点击链接上的“目标另存为...”后发送一个 GET 后跟一个 FIN、ACK,那么这就是导致管道损坏错误的原因.当您选择要保存文件的位置并点击浏览器中的“确定”按钮时,将发出另一个 GET。发生的事情是,一旦我检测到破损的管道,我仍然停留在 while True 循环中。所以我一直在继续从 Popen 对象中读取数据,但每次都无法将其发送给客户端。一旦完成,下一个 GET 就可以继续,然后传输就成功了。呸。

简而言之,工作代码:

import subprocess, socket

def send_video(sock, programme_id):
p = subprocess.Popen(["get_video","--pid",programme_id], stdout=subprocess.PIPE)
sock.send("HTTP/1.1 200 OK\nContent-type: application/octet-stream\n\n")
while True:
chunk = p.stdout.read(1024)
if chunk:
try:
sock.send(chunk)
except socket.error, e:
sock.close()
break
else:
break

def main():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('',8080))
s.listen(5)

while True:
client, address = s.accept()
data = client.recv(1024)
send_video(client, "123456")
client.close()

if __name__ == "__main__":
main()

谢谢。

关于python发送http响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5584755/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com