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

今天把上学期瞎折腾的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(BUFSIZ).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:


转载请标明出处

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值