基于python3实现聊天室程序(可发文件)

这篇博客分享了如何使用Python3编写一个简单的聊天室程序,包括群发消息、私聊以及文件传输功能。程序基于UDP服务,客户端通过继承Cmd模块实现命令行交互,服务器负责消息转发和用户管理。使用socket和json模块来处理网络通信和数据序列化。
摘要由CSDN通过智能技术生成

大家好,今天我给大家讲python3实现简单聊天室的具体代码。

好“故事”开始了

本文实例为大家分享了python3实现简单聊天室的具体代码,供大家参考,具体内容如下
(没有socket第三方库的朋友,在cmd里输入“pip install socket”)
刚刚接触python编程,又从接触C++(什么?不相信?看看我的主页再说,特别要看简介)开始一直对socket模块感兴趣,所以就做了一个聊天室的小程序。

该程序由客户端与服务器构成,使用UDP服务,服务器端绑定本地IP和端口,客户端由系统随机选择端口。

实现了群发、私发、点对点文件互传功能。

客户端自建了一个类继承了Cmd模块,使用自定义的命令command进行操作,调用相应的do_command方法。

使用json模块进行消息的封装序列化,在接收方进行解析。

客户端代码如下:

import socket
import threading
import json
import os
from cmd import Cmd
  
  
class Client(Cmd):
  """
  客户端
  """
  prompt = '>>>'
  intro = '[Welcome] 简易聊天室客户端(Cli版)\n' + '[Welcome] 输入help来获取帮助\n'
  buffersize = 1024
  
  def __init__(self, host):
    """
    构造
    """
    super().__init__()
    self.__socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    # self.__id = None
    self.__nickname = None
    self.__host = host
    self.thread_recv = None
    self.threadisalive = False
    # 是否在接收文件
    self.recvfile = False
    # 是否在发送文件
    self.sendfile = False
    self.filesize = None
    self.sendfilesize = None
  
    # 接收文件包计数
    self.filecount = None
    # 接收文件名
    self.filename = None
    # 发送文件名
    self.sendfilename = None
  
    # 发送者
    self.filefrom = None
    # 接收者
    self.fileto = None
  
    # 接收文件流
    self.file_recv = None
    # 发送文件流
    self.file_send = None
  
    # 接收文件地址
    self.filefrom_addr = None
    # 发送文件地址
    self.fileto_addr = None
  
  def __receive_message_thread(self):
    """
    接受消息线程
    """
    while self.threadisalive:
      # noinspection PyBroadException
      try:
        buffer, addr = self.__socket.recvfrom(1024)
        '''
        文件流由发送端直接发送,不经过服务器,故当发送端发来的消息时,将收到的数据存入文件
        '''
        if (addr != self.__host) & (addr == self.filefrom_addr) & self.recvfile:
          self.file_recv.write(buffer)
          self.filecount += 1
          if self.filecount * 1024 >= self.filesize:
            self.file_recv.close()
            print(self.filename, 'is received.')
            self.recvfile = False
          continue
  
        js = json.loads(buffer.decode())
  
        # 若接收的数据为消息信息,则显示
        if js['type'] == 'message':
          print(js['message'])
  
        # 若接收的数据为文件发送请求,则存储文件信息,并显示
        elif js['type'] == 'filequest':
          if self.recvfile:
            self.__socket.sendto(json.dumps({
   
              'type': 'fileres',
              'fileres': 'no',
              'nickname': self.__nickname,
              'who': js['nickname'],
              'errormessage': 'is transfroming files.',
            }).encode(), self.__host)
            continue
          filename = js['filename']
          who = js['nickname']
          filesize = js['filesize']
          self.recvfile = True
          self.filesize = filesize
          self.filename = filename
          self.filecount = 0
          self.filefrom = who
          self.filefrom_addr = (js['send_ip'], js['send_port'])
  
          print('[system]:', who, ' send a file(',
             filename, ') to you. receive? ')
  
        # 接受的数据为请求回复,若同意接收则存储服务器发来的接收方的地址,并开启发送线程
        elif js['type'] == 'fileres':
          if js['fileres'] == 'yes':
            print(js['recv_ip'], js['recv_port'])
            self.fileto_addr = (js['recv_ip'], js['recv_port'])
            thread = threading.Thread(
              target=self.__send_file_thread)
            thread.start()
          else:
            print(js['nickname'
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值