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线程的结束。


相关内容

热门资讯

空调连续工作多久需要停机休息 空调连续工作的时间取决于多个因素,包括空调的型号、功率、使用环境和维护情况等。一般来说,空调可以连续...
空调哪个符号是除湿的 空调除湿功能通常用一个水滴形状的符号表示。不同品牌和型号的空调遥控器可能会有所差异,但一般来说,除湿...
格力空调多长时间加一次氟利昂 1、一般情况下,空调对氟利昂的使用量是非常小的,所以在空调使用了四年左右的时候再考虑加也没问题。2、...
空调用多长时间需要加氟一次 一般情况下是五年。当出现以下这几种情况时,空调才需要加氟。1、空调的室内机和室外机各有两个接口,当接...
格调生活·C标思享荟:卡萨帝在... 9月12日的郑州龙湖金融岛,夜风轻拂,灯光璀璨。“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑...
品牌价值破千亿、高端份额持续领... 9月12日,“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑州站”在郑州龙湖金融岛举办。2026...
空调主板坏了修800还是换新的 空调主板坏了是修还是换新,需要考虑多个因素,以下是一些建议:1. 维修成本:如果维修费用较低,比如 ...
空调开多久需要休息多长时间 问题:空调开多久需要休息多长时间回答:1、在使用空调的过程中,一般空调开7~8个小时左右需要休息2~...
中央空调多长时间清洗一次 1、一般空调开机前清洗一次即可,空调开机中间时段再清洗一次,空调关机时清洗一次,这样比较合理。2、空...
中央空调氟利昂多久加一次 看空调制热和制冷程度,很多人的观点认为氟利昂必须一年放一次,其实这个观点是错误的,理解上面有点偏差,...