代码之家  ›  专栏  ›  技术社区  ›  Tony Chou

使用python3套接字连接到web服务器

  •  0
  • Tony Chou  · 技术社区  · 6 年前

    我在本地主机上运行python3运行django并收听 http://127.0.0.1:8000/

    我想用不同的方法来测试 request socket

    import requests
    res = requests.request("GET", "http://127.0.0.1:8000/")
    txt = res.content
    print(res)
    res.close()
    
    # <Response [200]>
    

    运行良好,并且

    在我运行的django控制台上,它显示 [07/Jul/2018 16:04:26] "GET / HTTP/1.1" 200 6744

    现在改成 requests 插座

    import socket
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect(('127.0.0.1', 8000))
    msg = b'GET / HTTP/1.1'
    s.send(msg)
    print(s)
    s.close()
    
    # <socket.socket fd=1324, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 55312), raddr=('127.0.0.1', 8000)>
    

    我的程序中没有显示错误

    但是在我运行的django控制台上出现了以下异常

    Invalid HTTP_HOST header: 'tony.jhou-1.xxservice.com:8000'. You may need to add 'tony.jhou-1.xxservice.com:8000' to ALLOWED_HOSTS.
    [07/Jul/2018 16:08:10] "GET / HTTP/1.1" 400 63266
    Traceback (most recent call last):
      File "C:\Users\tony.jhou\AppData\Local\Continuum\Anaconda3\lib\wsgiref\handlers.py", line 138, in run
        self.finish_response()
      File "C:\Users\tony.jhou\AppData\Local\Continuum\Anaconda3\lib\wsgiref\handlers.py", line 180, in finish_response
        self.write(data)
      File "C:\Users\tony.jhou\AppData\Local\Continuum\Anaconda3\lib\wsgiref\handlers.py", line 274, in write
        self.send_headers()
      File "C:\Users\tony.jhou\AppData\Local\Continuum\Anaconda3\lib\wsgiref\handlers.py", line 332, in send_headers
        self.send_preamble()
      File "C:\Users\tony.jhou\AppData\Local\Continuum\Anaconda3\lib\wsgiref\handlers.py", line 255, in send_preamble
        ('Date: %s\r\n' % format_date_time(time.time())).encode('iso-8859-1')
      File "C:\Users\tony.jhou\AppData\Local\Continuum\Anaconda3\lib\wsgiref\handlers.py", line 453, in _write
        result = self.stdout.write(data)
      File "C:\Users\tony.jhou\AppData\Local\Continuum\Anaconda3\lib\socketserver.py", line 775, in write
        self._sock.sendall(b)
      File "D:\emc\ve\lib\site-packages\gevent\_socket3.py", line 459, in sendall
        return _socketcommon._sendall(self, data_memory, flags)
      File "D:\emc\ve\lib\site-packages\gevent\_socketcommon.py", line 358, in _sendall
        timeleft = __send_chunk(socket, chunk, flags, timeleft, end)
      File "D:\emc\ve\lib\site-packages\gevent\_socketcommon.py", line 287, in __send_chunk
        data_sent += socket.send(chunk, flags)
      File "D:\emc\ve\lib\site-packages\gevent\_socket3.py", line 440, in send
        return _socket.socket.send(self._sock, data, flags)
    ConnectionAbortedError: [WinError 10053] 連線已被您主機上的軟體中止。
    [07/Jul/2018 16:08:10] "GET / HTTP/1.1" 500 59
    ----------------------------------------
    Exception happened during processing of request from ('127.0.0.1', 54587)
    Traceback (most recent call last):
      File "C:\Users\tony.jhou\AppData\Local\Continuum\Anaconda3\lib\wsgiref\handlers.py", line 138, in run
        self.finish_response()
      File "C:\Users\tony.jhou\AppData\Local\Continuum\Anaconda3\lib\wsgiref\handlers.py", line 180, in finish_response
        self.write(data)
      File "C:\Users\tony.jhou\AppData\Local\Continuum\Anaconda3\lib\wsgiref\handlers.py", line 274, in write
        self.send_headers()
      File "C:\Users\tony.jhou\AppData\Local\Continuum\Anaconda3\lib\wsgiref\handlers.py", line 332, in send_headers
        self.send_preamble()
      File "C:\Users\tony.jhou\AppData\Local\Continuum\Anaconda3\lib\wsgiref\handlers.py", line 255, in send_preamble
        ('Date: %s\r\n' % format_date_time(time.time())).encode('iso-8859-1')
      File "C:\Users\tony.jhou\AppData\Local\Continuum\Anaconda3\lib\wsgiref\handlers.py", line 453, in _write
        result = self.stdout.write(data)
      File "C:\Users\tony.jhou\AppData\Local\Continuum\Anaconda3\lib\socketserver.py", line 775, in write
        self._sock.sendall(b)
      File "D:\emc\ve\lib\site-packages\gevent\_socket3.py", line 459, in sendall
        return _socketcommon._sendall(self, data_memory, flags)
      File "D:\emc\ve\lib\site-packages\gevent\_socketcommon.py", line 358, in _sendall
        timeleft = __send_chunk(socket, chunk, flags, timeleft, end)
      File "D:\emc\ve\lib\site-packages\gevent\_socketcommon.py", line 287, in __send_chunk
        data_sent += socket.send(chunk, flags)
      File "D:\emc\ve\lib\site-packages\gevent\_socket3.py", line 440, in send
        return _socket.socket.send(self._sock, data, flags)
    ConnectionAbortedError: [WinError 10053] 連線已被您主機上的軟體中止。
    
    During handling of the above exception, another exception occurred:
    
    Traceback (most recent call last):
      File "C:\Users\tony.jhou\AppData\Local\Continuum\Anaconda3\lib\wsgiref\handlers.py", line 141, in run
        self.handle_error()
      File "D:\emc\ve\lib\site-packages\django\core\servers\basehttp.py", line 88, in handle_error
        super(ServerHandler, self).handle_error()
      File "C:\Users\tony.jhou\AppData\Local\Continuum\Anaconda3\lib\wsgiref\handlers.py", line 368, in handle_error
        self.finish_response()
      File "C:\Users\tony.jhou\AppData\Local\Continuum\Anaconda3\lib\wsgiref\handlers.py", line 180, in finish_response
        self.write(data)
      File "C:\Users\tony.jhou\AppData\Local\Continuum\Anaconda3\lib\wsgiref\handlers.py", line 274, in write
        self.send_headers()
      File "C:\Users\tony.jhou\AppData\Local\Continuum\Anaconda3\lib\wsgiref\handlers.py", line 331, in send_headers
        if not self.origin_server or self.client_is_modern():
      File "C:\Users\tony.jhou\AppData\Local\Continuum\Anaconda3\lib\wsgiref\handlers.py", line 344, in client_is_modern
        return self.environ['SERVER_PROTOCOL'].upper() != 'HTTP/0.9'
    TypeError: 'NoneType' object is not subscriptable
    
    During handling of the above exception, another exception occurred:
    
    Traceback (most recent call last):
      File "C:\Users\tony.jhou\AppData\Local\Continuum\Anaconda3\lib\socketserver.py", line 639, in process_request_thread
        self.finish_request(request, client_address)
      File "C:\Users\tony.jhou\AppData\Local\Continuum\Anaconda3\lib\socketserver.py", line 361, in finish_request
        self.RequestHandlerClass(request, client_address, self)
      File "C:\Users\tony.jhou\AppData\Local\Continuum\Anaconda3\lib\socketserver.py", line 696, in __init__
        self.handle()
      File "D:\emc\ve\lib\site-packages\django\core\servers\basehttp.py", line 155, in handle
        handler.run(self.server.get_app())
      File "C:\Users\tony.jhou\AppData\Local\Continuum\Anaconda3\lib\wsgiref\handlers.py", line 144, in run
        self.close()
      File "C:\Users\tony.jhou\AppData\Local\Continuum\Anaconda3\lib\wsgiref\simple_server.py", line 35, in close
        self.status.split(' ',1)[0], self.bytes_sent
    AttributeError: 'NoneType' object has no attribute 'split'
    

    我刚开始接触socket编程,刚开始学习网络,我想我应该发送更多的请求头。请告诉我怎么做,谢谢。

    1 回复  |  直到 6 年前
        1
  •  1
  •   ottomeister    6 年前

    是的,你需要发送更多的数据。最小的http 1.1请求需要包含 Host 头,指定应处理请求的主机的名称或地址,请求头行后面必须跟一个空行,以告诉服务器头已完全接收。

    在http中,行尾由一对字符表示,一个 回车 以及 换行 是的。在python字符串中 \r 表示回车和 \n 表示换行符。(换行符有时称为 新线 性格,因此 \ n个 这意味着你必须写 \r\n 标记请求中每一行的结尾。

    所以,你需要的是:

    msg = b'GET / HTTP/1.1\r\nHost: 127.0.0.1\r\n\r\n'
    

    决赛 \ r\n 生成指示标题结尾的空行。

    更改之后,服务器可能会报告另一个错误,因为客户端程序会立即关闭其套接字。这会中断客户端和服务器之间的连接。当服务器尝试发送其响应时,它将发现连接已断开,并且可能会对此抱怨。为了避免这种情况,请将客户更改为 s.recv 等待并从服务器读取响应 s.send() 是的。类似于:

    while True:
      resp = s.recv(8000)
      if resp:
        print resp
      else:
        break