Python网络编程基于多线程实现多用户全双工聊天功能
admin
2023-07-04 17:24:26
0

  多线程原理:TCP服务器会创建一个线程池,每当有客户端请求连接的时候,它便会从线程池中分配一个线程同客户端建立连接,当客户端中断连接后,线程便销毁。

  SocketServer 是标准库中一个高级别的模块。用于简化网络客户与服务器的实现。

  socketserver模块中分两大类:server类(解决连接问题)和request类(解决通信问题)

  我们将服务器做为中转站来处理信息,一方面与客户端互动,另一方面进行消息转发。

  大体思路确定下来后,需要确定一些通信规则:

  1. 客户端与服务器建立连接后,需要输入用户名登入,若用户名已存在,将reuse反馈给用户,用户输出错误信息,退出

  2. 用户输入正确的用户名后,即可进行通信了。如果未选择通信对象,则服务器会反馈信息,提示用户选择通信对象

  3. 选择通信对象的方法为,输入to:username,如果所选择的对象不存在,反馈错误信息,重新输入

  4.当正确选择通信对象后,双方建立连接,通过服务器中转信息进行通信

  5.在通信中,若发送‘quit',则结束发送消息的线程,并指示服务器该用户准备登出,服务器删除该用户后,反馈消息给用户,用户结束接收消息的线程并退出

  6.如果A正在与C通信,此时B向A发送信息,则A的通信窗口变为与B的通信窗口,即接收到B消息后,A发出的消息不再是给C,而是默认给B

  实现代码:

  #!/usr/bin/python

  'test TCP server'

  from socket import *

  from time import ctime

  import threading #多线程模块

  import re #正则表达式模块

  HOST = ''

  PORT = 21567

  BUFSIZ = 1024

  ADDR = (HOST, PORT)

  def Deal(sock, user):

  while True:

  data = sock.recv(BUFSIZ) #接收用户的数据

  if data == 'quit': #用户退出

  del clients[user]

  sock.send(data)

  sock.close()

  print '%s logout' %user

  break

  elif re.match('to:.+', data) is not None: #选择通信对象

  data = data[3:]

  if clients.has_key(data):

  chatwith[sock] = clients[data]

  chatwith[clients[data]] = sock

  else:

  sock.send('the user %s is not exist' %data)

  else:

  if chatwith.has_key(sock): #进行通信

  chatwith[sock].send("[%s] %s: %s" %(ctime(), user, data))

  else:

  sock.send('Please input the user who you want to chat with')

  tcpSerSock = socket(AF_INET, SOCK_STREAM)

  tcpSerSock.bind(ADDR)

  tcpSerSock.listen(5)

  clients = {} #提供 用户名->socket 映射

  chatwith = {} #提供通信双方映射

  while True:

  print 'waiting for connection...'

  tcpCliSock, addr = tcpSerSock.accept()

  print '...connected from:',addr

  username = tcpCliSock.recv(BUFSIZ) #接收用户名

  print 'The username is:',username

  if clients.has_key(username): #查找用户名

  tcpCliSock.send("Reuse") #用户名已存在

  tcpCliSock.close()

  else:无锡妇科医院排行 http://www.0510bhyy.com/

  tcpCliSock.send("Welcome!") #登入成功

  clients[username] = tcpCliSock

  chat = threading.Thread(target = Deal, args = (tcpCliSock,username)) #创建新线程进行处理

  chat.start() #启动线程

  tcpSerSock.close()

  #!/usr/bin/python

  'test tcp client'

  from socket import *

  import threading

  HOST = 'localhost'

  PORT = 21567

  BUFSIZ = 1024

  ADDR = (HOST, PORT)

  threads = []

  def Send(sock, test): #发送消息

  while True:

  data = raw_input('>')

  tcpCliSock.send(data)

  if data == 'quit':

  break

  def Recv(sock, test): #接收消息

  while True:

  data = tcpCliSock.recv(BUFSIZ)

  if data == 'quit':

  sock.close() #退出时关闭socket

  break

  print data

  tcpCliSock = socket(AF_INET, SOCK_STREAM)

  tcpCliSock.connect(ADDR)

  print 'Please input your username:',

  username = raw_input()

  tcpCliSock.send(username)

  data = tcpCliSock.recv(BUFSIZ)

  if data == 'Reuse':

  print 'The username has been used!'

  else:

  print 'Welcome!'

  chat = threading.Thread(target = Send, args = (tcpCliSock,None)) #创建发送信息线程

  threads.append(chat)

  chat = threading.Thread(target = Recv, args = (tcpCliSock,None)) #创建接收信息线程

  threads.append(chat)

  for i in range(len(threads)): #启动线程

  threads[i].start()

  threads[0].join() #在我们的设计中,send线程必然先于recv线程结束,所以此处只需要调用send的join,等待recv线程的结束。


相关内容

热门资讯

我国科学家为细胞信号“导航”开... 新华社济南5月31日电(记者张力元)人体细胞犹如一座精密的通信城市,每天都有大量“指令”穿梭传递,调...
极端大风突袭哈尔滨!过山车停摆... 极目新闻记者 詹钘5月31日,受强对流天气影响,哈尔滨国际会展中心体育场相关设施受到损坏,原计划当晚...
三原电缆取得电缆接头连接用防护... 国家知识产权局信息显示,上海三原电缆附件有限公司取得一项名为“一种电缆接头连接用防护结构”的专利,授...
原创 识... 还是那句话,机圈苦大屏久已…… 虽然大屏有大屏的美,但是小屏也有小屏的俏。在大屏旗舰占据主流的手机市...
玄戒技术取得分频电路专利,实现... 国家知识产权局信息显示,北京玄戒技术有限公司取得一项名为“分频电路、分频器、射频芯片和电子设备”的专...
为什么今年香会基调明显变了 5月29日—31日在新加坡举行的第23届香格里拉对话会(简称“香会”),见证着元首引领下大国关系继续...
成本几毛钱、假驱蚊液香精兑水,... 入夏升温,蚊虫进入活跃期,驱蚊防护成为民生刚需,《财经调查》持续接到消费者投诉,他们买到的多款网红驱...
越来越多80后90后,正在丧失... 六一儿童节到来之际,朋友圈里开始出现一种熟悉的热闹。有人晒出零食礼包,有人半开玩笑地向伴侣讨礼物,还...
洋保电子取得用于低温环境的电气... 国家知识产权局信息显示,洋保电子(太仓)有限公司取得一项名为“一种用于低温环境的电气柜”的专利,授权...
中日韩飞手争霸宁波!2026无... 潮新闻客户端 记者 陈冲 通讯员 朱凝 5月31日,2026小遛·无人机竞速世界杯(中国·宁波鄞州站...