gpt4 book ai didi

python - 如何启动连接到您正在监听的套接字的进程?

转载 作者:可可西里 更新时间:2023-11-01 02:41:47 25 4
gpt4 key购买 nike

我有一个进程,我的代码从 subprocess.Popen() 启动,它尝试连接到我的代码也在监听的套接字。问题是如果代码首先开始监听此套接字,则它无法启动子进程。被sock.accept()阻塞,当sock.accept()超时,subprocess.Popen()<时明显没有监听 运行。如果代码首先启动子进程,它会尝试连接到套接字,但在任何代码能够监听它之前就失败了。

现在..我有什么想法可以做到这一点吗?看起来我需要以非阻塞方式开始监听,然后启动进程,但我有点困惑,因为即使我使用 select() 来处理队列,最终 sock.accept() 被调用并且因此阻止了代码...我认为。

无论如何,一些方向会非常方便!我宁愿不这样做,但如果它能让生活更轻松,我也不反对使用 Twisted。

编辑 1:我将尝试以代码的方式进行改进,我必须查看我的旧提交以找到一个工作版本。不过基本上,我不认为我的代码是问题所在。我认为我只是实现错误。

例如,如果我启动我的套接字监听器并在 shell 中手动启动此 subprocess.Popen() 进程,它连接得很好。这是因为 shell 已经在监听。我相信我的问题只是先有鸡还是先有蛋的问题。在我的代码中,在单个代码路径中,如果我首先启动进程,它会立即失败,因为还没有 没有套接字服务器在监听。但是,如果我首先启动套接字服务器,它会超时,因为它正在阻塞,并且在它完成阻塞之前不会启动任何子进程。我相信,我的解决方案在于非阻塞代码,但我非常不熟悉如何正确实现这一点。我看到很多关于 select() 的提及,但它们看起来它们会在同一点阻塞,sock.accept()。我说“看起来像”是因为我还没有实现 select() 版本。我在这里可能是错的,如果我错了,请告诉我。

编辑 2:这是代码的套接字部分。请注意,这当前设置为非阻塞。

 90         # Create our socket stream to listen on.
91 serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
92
93 #serv.settimeout(5)
94 serv.setblocking(0)
95
96 # Bind the address.
97 serv.bind(('', self.PORT))
98 serv.listen(5)
99
100 try:
101 # Now start listening for a connection!
102 (self._sock, remote_address) = serv.accept()
103 except socket.timeout:
104 logger.debug('Socket connection failed!')
105 raise DBGPServerNotFoundError(
106 'No connection was established coming from '
107 '"%(address)s:%(port)i".' % {
108 'address':self.ADDRESS,
109 'port':self.PORT,
110 })
111 else:
112 logger.debug('Socket connection established! The other end of '
113 'the connection is at "%s:%i".' % remote_address)
114 finally:
115 serv.close()

这里是错误..

  File "/home/lee/projects/vim-debug/repo/vimbug/dbgp.py", line 100, in connect
(self._sock, remote_address) = serv.accept()
File "/usr/lib/python2.6/socket.py", line 197, in accept
sock, addr = self._sock.accept()
error: [Errno 11] Resource temporarily unavailable

子进程启动代码在不同的模块中(特别是单元测试),但这里是为了很好的衡量标准。注意con是一个容器对象,con.connect()是上面代码的函数。

 56     con.connect()
57 pydbgp_proc = subprocess.Popen(
58 ('pydbgp.py', '-d', 'localhost:%i' % OPTIONS['pydbgp_port'],
59 OPTIONS['debug_file']),
60 stdout=subprocess.PIPE,
61 stderr=subprocess.PIPE,)

编辑 3: 稍微重写代码以尝试在 sock.accept() 被调用之前连接到套接字。我们会看看它是否失败:)

编辑 4:好吧。稍微重写了代码..仍然有同样的错误。想法? (另外..这个编辑垃圾越来越大..在 stackoverflow 中是否有一些首选方法来进行这些大的更新/编辑?

代码:

 77     def listen(self):
78 # Create our socket stream to listen on.
79 serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
80
81 #serv.settimeout(5)
82 serv.setblocking(0)
83
84 # Bind the address.
85 serv.bind(('', self.PORT))
86 serv.listen(5)
87 self.serv = serv
88
89 def accept(self):
90 (newsock, newaddr) = self.serv.accept()

调用代码:

 57     con.listen()
58 pydbgp_proc = subprocess.Popen(
59 ('pydbgp.py', '-d', 'localhost:%i' % OPTIONS['pydbgp_port'],
60 OPTIONS['debug_file']),
61 stdout=subprocess.PIPE,
62 stderr=subprocess.PIPE,)
63 con.accept()

错误:

       File "/home/lee/projects/vim-debug/repo/vimbug/dbgp.py", line 90, in accept
(newsock, newaddr) = self.serv.accept()
File "/usr/lib/python2.6/socket.py", line 197, in accept
sock, addr = self._sock.accept()
error: [Errno 11] Resource temporarily unavailable

想法?

编辑 5: 我将接受函数更改为以下 select() 实现,这导致 'Not ready..?'正在打印。

 89     def accept(self):
90 rfds, wfds, xfds = select.select([self.serv], [], [], 1)
91
92 if self.serv in rfds:
93 print 'Read ready..?'
94 (newsock, newaddr) = self.serv.accept()
95 else:
96 print 'Not ready..?'

最佳答案

您是否在监听代码中设置了 socket.setblocking(0)

生成监听服务器后,您应该能够通过 select() 调用读取状态...对我来说在 debian lenny 和 python 2.5 下运行良好的示例...

import socket
import select

SERVER_SOCKADDR = ("", 424242)

server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setblocking(0) # <------------------
server.bind(SERVER_SOCKADDR)
server.listen(5)

client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.setblocking(0)

result = client.connect_ex(SERVER_SOCKADDR)

rfds, wfds, xfds = select.select([server], [client], [], 1)
if server in rfds:
print "Server socket: accept does not block"
sockfd, addr = server.accept() # sockfd.send() and sockfd.recv() to
# write and read the stream...
sockfd.setblocking(0)
print sockfd, addr
else:
print "Server socket: accept blocks"
if client in wfds:
print "Client socket: write does not block"
else:
print "Client socket: write blocks"


server.close()
client.close()

当我运行那个...

[mpenning@Bucksnort ~]$ python socket_test.py
Server socket: accept does not block
<socket._socketobject object at 0xb75764c4> ('127.0.0.1', 35810)
Client socket: write does not block
[mpenning@Bucksnort ~]$

关于python - 如何启动连接到您正在监听的套接字的进程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5697426/

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