【问题标题】:python sending http responsepython发送http响应
【发布时间】:2011-04-07 16:57:15
【问题描述】:

我正在尝试编写一个 非常 简单的 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 @987654321@ 发出 HTTP 请求,整个事情会按预期进行 - 视频将流式传输到客户端的套接字并附加到新文件 blah.mp4。

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

注意send_video() 中的try/except 块。我之前遇到过“管道损坏”错误(使用虚拟 HTML 页面方法),表明客户端的套接字不在那里可以写入。我把try/except 放在那里试图忽略它。

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

有什么想法吗?

编辑:

来自 wget 的标题:

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 个 GET 请求,用于虚拟 html 链接方法。我在这里看不到任何明显的东西...

【问题讨论】:

  • 从客户端收到data 后打印。也许第一个请求只是HEAD 或者像这样只查询你的服务器
  • 为什么不使用SimpleHTTPServer
  • 您可以使用 Wireshark 找出不同之处。
  • 我和@pajton 在一起。您应该阅读并打印出传入的请求,以便查看发生了什么。
  • 感谢您的回复。我在下面添加了一条回复以显示 GET 请求。

标签: python http sockets popen


【解决方案1】:

我突然意识到,因为在链接上单击“目标另存为...”之后,浏览器会发送一个 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()

谢谢。

【讨论】:

  • 如果确实如此,请不要忘记将其添加为您的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-06
  • 1970-01-01
  • 1970-01-01
  • 2017-07-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多