【问题标题】:Why do I need `Ctrl-c` when `curl` to the this tcp proxy为什么当“curl”到这个 tcp 代理时我需要“Ctrl-c”
【发布时间】:2016-02-18 08:50:16
【问题描述】:

我正在尝试让this tcp proxy 工作。我使用了一个基于BaseHTTPServer的简单服务器

  1. 在端口 12343 上运行服务器
  2. 在端口 12344 上运行代理
  3. 对端口 12343 运行 curl。它有效!
  4. 对端口 12344 运行 curl。现在我需要按 Ctrl-C

Here is the code 以及如何重现这种情况:

$ ./server0.py  12343

$ ./relay.py 12344 127.0.0.1 12343

$ curl 'http://localhost:12343' # This works fine

$ curl 'http://localhost:12344' # This needs Ctrl-c 

PS:另一个问题是如何在 relay.py 运行后停止它。 Ctrl-C 不起作用。目前,我正在使用Ctrl-zkill `jobs -ps`

【问题讨论】:

  • 我猜是因为HTTP连接没有被服务器关闭?
  • @adarsh 我同意,但我不知道应该在哪里关闭它

标签: python sockets curl proxy


【解决方案1】:

这是因为你忘记关闭客户端(curl)和中继之间的连接。

BaseHTTPServer在写完响应后会关闭TCP连接,所以直接连接HTTP服务器就可以了。

但是,当通过中继连接到 HTTP 服务器时,连接将是这样的

                   --Relay-------
                  |   pipe1     |
      connection1 | ----------> | connection2
    | ----------->|/           \|------------> |
curl|             |             |              | HTTP Server
    | <-----------|\  pipe2    /|<------------ |
                  |  <--------- |

connection2 会被 HTTP Server 关闭,但是 connection1 不会,所以 curl 会一直挂起。

要解决问题,只需调用 socket.shutdown() 在connection1上,修改后的PipeThread.run()如下:

def run(self):
        while True:
            try:
                data = self.source.recv(1024)
                if not data:
                    break
                self.sink.send(data)
            except Exception as e:
                logging.error(e)
                break
        logging.info('%s terminating' % self)

        self.sink.shutdown(socket.SHUT_WR) #close the socket on the write side

        PipeThread.pipes.remove(self)
        logging.info('%s pipes active' % len(PipeThread.pipes))

完整代码修改代码为here

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-12-22
    • 2011-08-05
    • 1970-01-01
    • 2020-11-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多