您的位置:首页 > 编程语言 > Python开发

Python3 多线程下实现C/S交互模型

2018-03-18 23:18 477 查看
今天把上学期瞎折腾的TCP C/S交互模型重写了一下,上学期是参考《Python核心编程》教程中的示例改写的,但过于简单,中心机能同时连接多台节点机,但无法交互,作为改进,便用多线程实现交互过程(C端启动2个线程,一个用于接收,另一个用于发送)。欢迎大家改进!
TCPserver.py# coding=utf-8
'''Author:Frank.ZhangLongqi
Date:2017-3-18
Environment:Win8,Python3.6
E-mail:2925696434@qq.com
Description:这是主程序,用于启动线程监听客户端的连接,并与客户端通信,可以同时和多个客户端通信;
Improvement:可以加入守护线程
'''
from socket import *
from time import ctime
import re,time
from atexit import register
from threading import Thread,Lock,BoundedSemaphore
import threading

HOST=' '
PORT=21567
BUFSIZ=1024
ADDR=(HOST,PORT)
lock = Lock()
MAX = 3#设置同时连接3个C端
pool = BoundedSemaphore(MAX)
n=3

tcpSerSock = socket(AF_INET,SOCK_STREAM)
tcpSerSock.bind(ADDR)
tcpSerSock.listen(5)

def connect():
global n
lock.acquire()
pool.acquire()
tcpCliSock,addr = tcpSerSock.accept()
lock.release()
print('...connected from:',addr)

while True:
data = tcpCliSock.recv(BUFSIZ).decode()
if not data:
#print(str(addr[0])+':'+str(addr[1])+": \"Goodbye\"")
print(str(threading.currentThread().getName())+": \"Goodbye\"")
print("There are remaining the number of threads is:",len(threading.enumerate())-2)
break
print(str(threading.currentThread().getName())+": \""+data+"\"")
time.sleep(0.5)
while True:
data_to=input("to"+str(threading.currentThread().getName())+">")
if data_to.strip()=="rcv":#输入"rcv"相当于退出输入状态,而转向接收状态
break
data_to='['+ctime()+'] '+data_to
tcpCliSock.send(data_to.encode())
time.sleep(2)
lock.acquire()
pool.release()
lock.release()
tcpCliSock.close()

#tcpSerSock.close()
def main():
print("start at:",ctime())
print('waiting for connection...')
L=[]
global n
for i in range(n):
t=Thread(target=connect,args=())
L.append(t)
for i in L:
i.start()
for i in L:
i.join()
@register
def _atexit():
print('all DONE at:',ctime())
if __name__ == '__main__':
main()

TCPclient.py# coding=utf-8
'''每个C端都有1个接收线程和1个发送线程'''
from socket import *
import threading
import time
HOST = '127.0.0.1'
PORT = 21567
BUFSIZ = 1024
ADDR = (HOST,PORT)

tcpCliSock = socket(AF_INET,SOCK_STREAM)
tcpCliSock.connect(ADDR)
def send():
while True:
data = input('>')
if data.strip()=="exit":
break
tcpCliSock.send(data.encode())
time.sleep(2)
tcpCliSock.close()
def recv():
while True:
data_recv = tcpCliSock.recv(B
94fe
UFSIZ).decode()
print(data_recv)
time.sleep(5)

if __name__=="__main__":
s=threading.Thread(target=send,args=())#发送线程
r=threading.Thread(target=recv,args=())#接收线程
s.start()
r.start()
s.join()
r.join()
Demon:一个S端,3个C端
S(erver):Thread-1表示线程1发来的消息,toThread-1表示发给线程1的消息(键盘输入),空回车可以实现回复的对象在Thread-1~3间切换



C1:输入exit表示退出连接,有时间戳打头的行是收到的消息,没有则是键盘输入要发送的Message



C2:



C3:



转载请标明出处
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: