执行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()

  

 

posted @ 2016-12-18 22:50  Vincen_shen  阅读(762)  评论(0)    收藏  举报