执行shell命令的多进程多连接Socket
直接使用多进程来实现会报错:
OSError: [WinError 10048] Only one usage of each socket address (protocol/network address/port) is normally permitted
--------------------------------------------------------------------------------------------
我们都知道socket是网络上两个进程之间的双向通信链路, 即
socket = 《A进程的IP地址:端口号,B进程的IP地址:端口号》
那么有个问题就很有意思了,不同的进程可以监听在同一个IP地址:端口号么?
根据Unix网络编程中的知识可知,服务端监听一个端口会经历:
1、根据套接字类型(Ipv4,Ipv6等)创建套接字socket
2、将套接字bind绑定到具体的网络地址和端口号
3、调用listen开始在这个套接字上进行监听。
Unix提供了一个接口setsockopt()可以在bind之前设置套接字选项,其中就包括REUSEADDR这个选项,表明可以多个进程复用bind函数中指定的地址和端口号。
由此可知多个应用(进程),包括同一个应用多次,都是可以绑定到同一个端口进行监听的。对应地C++、NET等高级语言也都提供了对应的接口。
--------------------------------------------------------------------------------------------
import socket import subprocess import multiprocessing ''' 多进程实现多客户端同时连接,需要注意的默认情况下系统中每个进程占用一个端口,而不允许两个进程同时占用一个端口, 所以需要在s.bind()前使用setsocketopt来允许端口复用: s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) 这里value设置为1,表示将SO_REUSEADDR标记为TRUE, 操作系统会在服务器socket被关闭或服务器进程终止后马上释放该服务器的端口,否则操作系统会保留几分钟该端口。 ''' host = '' port = 8001 buffersize = 1024 # 方便今后扩展 address = (host,port) # 方便今后扩展 s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) s.bind(address) def cmd(conn,addr): while True: data = bytes.decode(conn.recv(buffersize)) result = subprocess.check_output(data,shell=True) count = len(result) print('count:',count) conn.send(bytes(str(count),encoding='utf8')) while count > 0 : count2 = conn.send(result) count = count - count2 conn.close() while True: s.listen(10) conn,addr = s.accept() print('Connect by:',addr) process = multiprocessing.Process(target=cmd,args=(conn,addr)) # 启动多线程来实现多个客户端同时连接,否则只能同时一个客户端连接。 process.start() process.join() s.close()