Python:更好的打开多个套接字的方法
我有一个程序,用来打开很多个网络连接(也就是“套接字”),并保持这些连接打开,以便对我们的服务器进行压力测试。不过,这个程序有几个问题。我觉得它可以比现在的递归调用更高效,而且它实际上还是一个一个地打开连接,而不是同时打开。我知道有一些工具,比如ab,可能可以模拟我想做的事情,但我希望能增加我的Python知识。我是不是应该把这个程序改写成多线程或者多进程的方式呢?
> #!/usr/bin/env python
>
> import socket, time, sys
> sys.setrecursionlimit(2000)
>
> def open_socket(counter):
> sockname = "s" + str(counter)
> port = counter + 3000
> sockname = socket.socket()
> sockname.bind(('localhost', port))
> sockname.listen(1)
> if counter == 2:
> time.sleep(20)
> elif counter > 2:
> counter = counter -1
> open_socket(counter)
>
> open_socket(1500)
3 个回答
0
其实这个已经是多进程了——在调用 open_socket 之前加个睡眠,然后从命令行运行,比如说 500 个这样的进程:
for i in `seq 500`; do ./yourprogram & done
不过你实际上并没有连接到什么东西——看起来你是在设置服务器套接字?如果你需要连接到某个东西,肯定应该用并行处理来测试一下(比如多线程,或者像上面那样运行很多进程,或者使用异步连接)。这个链接值得一读:
2
你可以试试用Twisted来解决这个问题。它可以让Python的网络编程变得简单很多。他们的网站上有一些教程,可以帮助你入门。
不过,用Python来做这个任务可能有点过于复杂了。一个更快的办法是直接打开1500个nc的实例:
for i in {3000..4500};
do
nc -l -p $i &
done
4
我一直搞不懂为什么要用递归而不是简单的循环。我的猜测是,使用简单的循环时,你会一次又一次地覆盖变量sockname,这样Python的垃圾回收机制就会在你创建下一个socket时关闭之前的那个。解决办法是把它们都存储在一个列表里,这样就能防止Python把它们回收掉:
def open_socket(counter):
sockets = []
for i in range(counter):
s = socket.socket()
s.bind(('localhost', i+3000))
s.listen(1)
sockets.append(s)
time.sleep(20)
另外注意,你代码中的第一次给sockname赋值是多余的,因为它会被第二次赋值覆盖掉。