Py004-01-18多线程实现并发套接字

多线程实现并发套接字

非并发套接字(最初版)

server.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import socket

phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
phone.bind(('127.0.0.1',8083)) #0-65535:0-1024给操作系统使用
phone.listen(5)

print('starting...')
while True: # 链接循环
conn,client_addr=phone.accept()
print(client_addr)

while True: #通信循环
try:
data=conn.recv(1024)
if not data:break #适用于linux操作系统
print('客户端的数据',data)

conn.send(data.upper())
except ConnectionResetError: #适用于windows操作系统
break
conn.close()

phone.close()

client.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import socket

phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)

phone.connect(('127.0.0.1',8081))

while True:
msg=input('>>: ').strip() #msg=''
if not msg:continue
phone.send(msg.encode('utf-8')) #phone.send(b'')
# print('has send')
data=phone.recv(1024)
# print('has recv')
print(data.decode('utf-8'))

phone.close()

并发版本

仅仅需改善server.py

线程版本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
from socket import *
from threading import Thread

def communicate(conn):
while True:
try:
data=conn.recv(1024)
if not data:break
conn.send(data.upper())
except ConnectionResetError:
break

conn.close()

def server(ip,port):
server = socket(AF_INET, SOCK_STREAM)
server.bind((ip,port))
server.listen(5)

while True:
conn, addr = server.accept()
t=Thread(target=communicate,args=(conn,))
t.start()

server.close()

if __name__ == '__main__':
server('127.0.0.1', 8081)

线程池版本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
from socket import *
from concurrent.futures import ThreadPoolExecutor

def communicate(conn):
while True:
try:
data=conn.recv(1024)
if not data:break
conn.send(data.upper())
except ConnectionResetError:
break

conn.close()

def server(ip,port):
server = socket(AF_INET, SOCK_STREAM)
server.bind((ip,port))
server.listen(5)

while True:
conn, addr = server.accept()
pool.submit(communicate,conn)

server.close()

if __name__ == '__main__':
pool=ThreadPoolExecutor(2)
server('127.0.0.1', 8081)