如何打开一个TCP套接字来监听一个连接并返回结果?
我正在尝试编写一个打开端口(戳第三方)的脚本,然后捕获并返回他们的 http 请求中有趣的部分,以便我的主线程继续。
第三方认为我们是一个http网络服务器。到目前为止,我正在尝试使用 TCPServer.SocketServer
(或 http.server.HTTPServer
)来执行此操作。到目前为止,对于“戳”部分,我正在使用浏览器手动点击它。但问题是:
如何将数据返回到主线程?
由于socketserver.TCPServer消耗的是一个类,而不是类的实例,所以我不知道如何将数据传回父线程。这也许就是并发编程101?我希望“返回”该值,但我想一些跨线程共享变量就可以了。
当前的代码看起来很像:
async def fourtytwo(text):
pprint.pp(text)
return 42
class MyTCPHandler(socketserver.BaseRequestHandler):
data = None
def handle(self):
self.data = self.request.recv(1024).strip()
print("{} wrote:".format(self.client_address[0]))
print(self.data)
# just send back the same data, but upper-cased
self.request.sendall(self.data.upper())
async def listen_for_response():
logger = logging.getLogger(inspect.currentframe().f_code.co_name)
logger.debug("Listening on port: %s", LISTENING_PORT)
with socketserver.TCPServer(("localhost", LISTENING_PORT), MyTCPHandler) as server:
server.handle_request()
code = MyTCPHandler.data
logger.debug("Code is: %s", code)
logger.debug("Exiting")
return code
async def flow(config):
onetwo = await asyncio.gather(
fourtytwo("one"),
asyncio.create_task(listen_for_response()),
)
pprint.pp(onetwo)
输出:
DEBUG:listen_for_response:Listening on port: 4200
127.0.0.1 wrote:
b'GET / HTTP/1.1\r\nHost: localhost:4200\r\nUser-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:97.0) Gecko/20100101 Firefox/97.0\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8\r\nAccept-Language: en-US,en;q=0.5\r\nAccept-Encoding: gzip, deflate\r\nDNT: 1\r\nConnection: keep-alive\r\nUpgrade-Insecure-Requests: 1\r\nSec-Fetch-Dest: document\r\nSec-Fetch-Mode: navigate\r\nSec-Fetch-Site: none\r\nSec-Fetch-User: ?1\r\nCache-Control: max-age=0'
DEBUG:listen_for_response:Code is: None
DEBUG:listen_for_response:Exiting
'one'
[42, None]
I'm trying to write a script which opens a port, (pokes a third party), then captures and returns the interesting part of their http request for my main thread to continue with.
The third party thinks we are an http webserver. TCPServer.SocketServer
(or http.server.HTTPServer
) are, so far, what I'm attempting to do this with. So far, for the "poke" part I'm manually hitting it with the browser. But the question is:
How to return the data to the main thread?
Since socketserver.TCPServer consumes a class, not an instance of a class, I do not know how to pass the data back to parent thread. This is perhaps Concurrent Programming 101? I was hoping to "return" the value, but I suppose some cross thread shared variable will do.
The current code looks a lot like:
async def fourtytwo(text):
pprint.pp(text)
return 42
class MyTCPHandler(socketserver.BaseRequestHandler):
data = None
def handle(self):
self.data = self.request.recv(1024).strip()
print("{} wrote:".format(self.client_address[0]))
print(self.data)
# just send back the same data, but upper-cased
self.request.sendall(self.data.upper())
async def listen_for_response():
logger = logging.getLogger(inspect.currentframe().f_code.co_name)
logger.debug("Listening on port: %s", LISTENING_PORT)
with socketserver.TCPServer(("localhost", LISTENING_PORT), MyTCPHandler) as server:
server.handle_request()
code = MyTCPHandler.data
logger.debug("Code is: %s", code)
logger.debug("Exiting")
return code
async def flow(config):
onetwo = await asyncio.gather(
fourtytwo("one"),
asyncio.create_task(listen_for_response()),
)
pprint.pp(onetwo)
And outputs:
DEBUG:listen_for_response:Listening on port: 4200
127.0.0.1 wrote:
b'GET / HTTP/1.1\r\nHost: localhost:4200\r\nUser-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:97.0) Gecko/20100101 Firefox/97.0\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8\r\nAccept-Language: en-US,en;q=0.5\r\nAccept-Encoding: gzip, deflate\r\nDNT: 1\r\nConnection: keep-alive\r\nUpgrade-Insecure-Requests: 1\r\nSec-Fetch-Dest: document\r\nSec-Fetch-Mode: navigate\r\nSec-Fetch-Site: none\r\nSec-Fetch-User: ?1\r\nCache-Control: max-age=0'
DEBUG:listen_for_response:Code is: None
DEBUG:listen_for_response:Exiting
'one'
[42, None]
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
放弃
socketserver
并直接打开套接字更容易,也许是必要的:It was easier, perhaps necessary, to abandon
socketserver
and instead open a socket directly: