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:
转载请标明出处
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:
转载请标明出处
相关文章推荐
- python用于实现多线程异步交互之生产者消费者模型
- 【Python之旅】第六篇(五):生产者消费者模型实现多线程异步交互
- 生产者消费者模型实现多线程异步交互
- python3中实现客户端与服务端交互发送文件
- python-82:交互部分模拟实现的源码
- [多线程] 生产者消费者模型的BOOST实现
- javascript多线程--web workers实现线程间数据交互的小测试
- Python多线程下载文件如何实现?
- 一行 Python 实现并行化 -- 日常多线程操作的新思路 - 左手键盘,右手书 - SegmentFault
- Java的多线程编程模型5--从AtomicInteger开始(自增长实现)
- 基于回归曲线拟合模型的ALS(最小二乘法)推导过程以及Python实现
- boost中asio网络库多线程并发处理实现,以及asio在多线程模型中线程的调度情况和线程安全。
- 多线程模拟实现生产者/消费者模型
- python编写类来实现生产者消费者模型
- python 多线程 基于正则表达式的多线程文本替换功能实现
- python实现多线程抓取知乎用户
- python:threading多线程模块-Condition实现复杂的同步
- Python 多线程 生产者消费者模型
- Servlet多线程模型实现
- 最大熵模型与EM算法及python实现