资讯专栏INFORMATION COLUMN

基于Python socket实现简易网络聊天室

89542767 / 278人阅读

  小编写这篇文章的主要目的,主要介绍的是关于Python socket的相关知识,介绍的内容主要是涉及到编程的一些事情,以此用来进行搭建简易的网络聊天室,来实现相关的远程聊天,这其实就是聊天工具的初始原型,下面就具体的内容给大家详细解答下。


  在这个周末刚刚写出来的python桌面应用--网络聊天室,主要通过pyqt5作为桌面应用框架,socket作为网络编程的框架,从而实现包括客户端和服务端的网络聊天室的GUI应用,希望可以一起学习、一起进步!


  应用包括服务端server_ui.py、客户端client_ui.py两个python模块实现,并且在pyqt5的使用过程中都使用QThread多线程应用以及基本的UI页面布局。开始之前通过一个动态图来观察一下socket服务端、socket客户端通信的实现效果。


  1.socket_ui.py服务端


  1-1.依赖引用


  在socket服务端的实现过程中,除了pyqt5相关的UI界面的引用外,还包括time、threading、sys、socket等辅助模块来一起实现socket服务端的桌面应用程序。


  from PyQt5.QtWidgets import*
  from PyQt5.QtCore import*
  from PyQt5.QtGui import*
  import sys
  from QCandyUi import CandyWindow
  #导入socket通讯模块
  import socket
  #导入时间管理模块
  import time
  #导入多线程模块
  import threading


  1-2.实现过程


  在服务端的业务实现上面,我们依然是按照之前的GUI实现方式,采用主线程用来实现页面布局,子线程QThread来实现业务逻辑的方式来进行实现的,socket的服务端通信业务都是在子线程ServerThread中编写的。下面是socket服务端桌面应用实现的全部代码块,copy到自己的ide中即可直接启动使用。


  class ServerUI(QWidget):
  def __init__(self):
  super(ServerUI,self).__init__()
  self.init_ui()
  def init_ui(self):
  self.setWindowTitle('socket服务端公众号:[Python集中营]')
  self.setWindowIcon(QIcon('hi.ico'))
  self.setFixedSize(500,300)
  hbox=QHBoxLayout()
  hbox_v1=QVBoxLayout()
  self.brower=QTextBrowser()
  self.brower.setFont(QFont('宋体',8))
  self.brower.setReadOnly(True)
  self.brower.setPlaceholderText('消息展示区域...')
  self.brower.ensureCursorVisible()
  hbox_v1.addWidget(self.brower)
  hbox_v2=QVBoxLayout()
  hbox_v2_f1=QFormLayout()
  self.ip_label=QLabel()
  self.ip_label.setText('ip地址')
  self.ip_txt=QLineEdit()
  self.ip_txt.setPlaceholderText('0.0.0.0')
  self.port_label=QLabel()
  self.port_label.setText('端口')
  self.port_txt=QLineEdit()
  self.port_txt.setPlaceholderText('4444')
  self.lis_num_label=QLabel()
  self.lis_num_label.setText('最大监听个数')
  self.lis_num_txt=QLineEdit()
  self.lis_num_txt.setPlaceholderText('10')
  self.close_cli_label=QLabel()
  self.close_cli_label.setText('客户端关闭指令')
  self.close_cli_txt=QLineEdit()
  self.close_cli_txt.setPlaceholderText('exit,客户端发送相应指令则关闭')
  hbox_v2_f1.addRow(self.ip_label,self.ip_txt)
  hbox_v2_f1.addRow(self.port_label,self.port_txt)
  hbox_v2_f1.addRow(self.lis_num_label,self.lis_num_txt)
  hbox_v2_f1.addRow(self.close_cli_label,self.close_cli_txt)
  self.start_btn=QPushButton()
  self.start_btn.setText('开启服务端')
  self.start_btn.clicked.connect(self.start_btn_clk)
  hbox_v2.addLayout(hbox_v2_f1)
  hbox_v2.addWidget(self.start_btn)
  hbox.addLayout(hbox_v1)
  hbox.addLayout(hbox_v2)
  self.thread_=ServerThread(self)
  self.thread_.message.connect(self.show_message)
  self.setLayout(hbox)
  def show_message(self,text):
  '''
  槽函数:向文本浏览器中写入内容
  :param text:
  :return:
  '''
  cursor=self.brower.textCursor()
  cursor.movePosition(QTextCursor.End)
  self.brower.append(text)
  self.brower.setTextCursor(cursor)
  self.brower.ensureCursorVisible()
  def start_btn_clk(self):
  self.thread_.start()
  self.start_btn.setEnabled(False)
  class ServerThread(QThread):
  message=pyqtSignal(str)
  def __init__(self,parent=None):
  super(ServerThread,self).__init__(parent)
  self.parent=parent
  self.working=True
  def __del__(self):
  self.working=False
  self.wait()
  def run(self):
  self.message.emit('准备启动socket服务端...')
  #创建服务端socket
  socket_server=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
  #绑定服务地址、端口
  address=(self.parent.ip_txt.text().strip(),int(self.parent.port_txt.text().strip()))
  socket_server.bind(address)
  #设置监听最大等待数
  socket_server.listen(int(self.parent.lis_num_txt.text().strip()))
  self.message.emit("服务已经启动,正在等待客户端连接...")
  while True:
  #设置睡眠时间
  time.sleep(0.1)
  #允许客户端连接
  client,info=socket_server.accept()
  self.client,self.info=client,info
  #启用新线程调用消息处理
  thread=threading.Thread(target=self.catch_message)
  #设置为守护线程
  thread.setDaemon(True)
  #开启线程执行
  thread.start()
  def catch_message(self):
  self.client.send("欢迎来到网络聊天室".encode('utf-8'))
  self.message.emit("客户端信息:"+str(self.info))
  close_cli=self.parent.close_cli_txt.text().strip()
  while True:
  try:
  #接收客户端消息、接收最大长度为1024,并进行utf-8解码
  message=self.client.recv(1024).decode('utf-8')
  #校验是否关闭客户端
  if not message and close_cli==message:
  self.client.close()
  self.message.emit("当前客户端已关闭!")
  break
  self.message.emit("接收到消息:"+message)
  #将消息进行utf-8编码后发给客户端
  rcv="服务端成功接收消息:"+message
  self.client.send(rcv.encode('utf-8'))
  except Exception as e:
  self.client.send("服务端处理消息异常!".encode('utf-8'))
  break
  if __name__=='__main__':
  app=QApplication(sys.argv)
  w=CandyWindow.createWindow(ServerUI(),theme='blueGreen',title='socket服务端公众号:[Python集中营]',
  ico_path='hi.ico')
  w.show()
  sys.exit(app.exec_())


  1-3.实现效果

03.png

  2.client_ui.py客户端


  在socket客户端的实现过程中,除了pyqt5相关的UI界面的引用外,还包括sys、socket等辅助模块来一起实现socket服务端的桌面应用程序,相比服务端来说,客户端并没有使用多线程threading模块。


  from PyQt5.QtWidgets import*
  from PyQt5.QtCore import*
  from PyQt5.QtGui import*
  import sys
  from QCandyUi import CandyWindow
  #导入socket通信模块
  import socket


  2-2.实现过程


  客户端的实现过程和服务端server_ui.py实现是基本相似的,同样也使用到了pyqt5的QThread的子线程应用,唯一不同的是socket客户端通信方式跟服务端不大相同,同样将下面的代码块copy到自己的ide中直接使用即可。


  class ClientUI(QWidget):
  def __init__(self):
  super(ClientUI,self).__init__()
  self.init_ui()
  def init_ui(self):
  self.setWindowTitle('socket客户端公众号:[Python集中营]')
  self.setWindowIcon(QIcon('hi.ico'))
  self.setFixedSize(500,300)
  hbox=QHBoxLayout()
  hbox_v1=QVBoxLayout()
  self.brower=QTextBrowser()
  self.brower.setFont(QFont('宋体',8))
  self.brower.setReadOnly(True)
  self.brower.setPlaceholderText('消息展示区域...')
  self.brower.ensureCursorVisible()
  hbox_v1.addWidget(self.brower)
  hbox_v2=QVBoxLayout()
  hbox_v2_g1=QGridLayout()
  self.ip_label=QLabel()
  self.ip_label.setText('ip地址')
  self.ip_txt=QLineEdit()
  self.ip_txt.setPlaceholderText('0.0.0.0')
  self.port_label=QLabel()
  self.port_label.setText('端口')
  self.port_txt=QLineEdit()
  self.port_txt.setPlaceholderText('4444')
  self.message=QTextEdit()
  self.message.setPlaceholderText('发送消息内容...')
  hbox_v2_g1.addWidget(self.ip_label,0,0,1,1)
  hbox_v2_g1.addWidget(self.ip_txt,0,1,1,1)
  hbox_v2_g1.addWidget(self.port_label,1,0,1,1)
  hbox_v2_g1.addWidget(self.port_txt,1,1,1,1)
  hbox_v2_g1.addWidget(self.message,2,0,1,2)
  self.start_btn=QPushButton()
  self.start_btn.setText('发送消息')
  self.start_btn.clicked.connect(self.start_btn_clk)
  hbox_v2.addLayout(hbox_v2_g1)
  hbox_v2.addWidget(self.start_btn)
  hbox.addLayout(hbox_v1)
  hbox.addLayout(hbox_v2)
  self.thread_=ClientThread(self)
  self.thread_.message.connect(self.show_message)
  self.setLayout(hbox)
  def show_message(self,text):
  '''
  槽函数:向文本浏览器中写入内容
  :param text:
  :return:
  '''
  cursor=self.brower.textCursor()
  cursor.movePosition(QTextCursor.End)
  self.brower.append(text)
  self.brower.setTextCursor(cursor)
  self.brower.ensureCursorVisible()
  def start_btn_clk(self):
  self.thread_.start()
  class ClientThread(QThread):
  message=pyqtSignal(str)
  def __init__(self,parent=None):
  super(ClientThread,self).__init__(parent)
  self.parent=parent
  self.working=True
  self.is_connect=False
  def __del__(self):
  self.working=False
  self.wait()
  def run(self):
  try:
  if self.is_connect is False:
  self.connect_serv()
  #将控制台输入消息进行utf-8编码后发送
  self.socket_client.send(self.parent.message.toPlainText().strip().encode('utf-8'))
  self.message.emit(self.socket_client.recv(1024).decode('utf-8'))
  except Exception as e:
  self.message.emit("发送消息异常:"+str(e))
  def connect_serv(self):
  try:
  self.message.emit("正在创建客户端socket...")
  #创建客户端socket
  self.socket_client=socket.socket()
  #连接服务端
  address=(self.parent.ip_txt.text().strip(),int(self.parent.port_txt.text().strip()))
  self.socket_client.connect(address)
  self.message.emit("服务端连接成功...")
  #接收服务端消息并进行utf-8解码
  self.message.emit(self.socket_client.recv(1024).decode())
  self.is_connect=True
  except:
  self.is_connect=False
  if __name__=='__main__':
  app=QApplication(sys.argv)
  w=CandyWindow.createWindow(ClientUI(),theme='blueGreen',title='socket客户端公众号:[Python集中营]',
  ico_path='hi.ico')
  w.show()
  sys.exit(app.exec_())

       综上所述,这篇文章就给大家介绍完毕,希望可以给大家带来帮助。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/128396.html

相关文章

  • 基于express和socket.io的简易天室

    摘要:简易版聊天室技术栈功能实现实时聊天创建房间表情包完善私聊效果登录服务端判断之前是否登录过聊天室,如果是则直接进入聊天室,否则跳转到登录页面。客户端发送创建房间和切换房间的事件给服务端。 Chat 简易版聊天室 技术栈 express socket.io 功能 实现 实时聊天 创建房间 表情包 完善 私聊 效果 登录 showImg(https://segmentfa...

    dendoink 评论0 收藏0
  • 利用express+socket.io实现一个简易天室

    摘要:用伪代码来模拟下长轮询的过程前端利用下面函数进行请求后端代码做如下更改利用随机数的大小来模拟是否有新数据有新数据来了长轮询的确减少了请求的次数,但是它也有着很大的问题,那就是耗费服务器的资源。 写在前面 最近由于利用node重构某个项目,项目中有一个实时聊天的功能,于是就研究了一下聊天室,在线demo|源码,欢迎大家反馈。这个聊天室的主要利用到了socket.io和express。这个...

    Chaz 评论0 收藏0
  • vue+socket.io+express+mongodb 实现简易多房间在线群聊

    摘要:项目简介主要是通过做一个多人在线多房间群聊的小项目来练手全栈技术的结合运用。编译运行开启服务,新建命令行窗口启动服务端,新建命令行窗口启动前端页面然后在浏览器多个窗口打开,注册不同账号并登录即可进行多用户多房间在线聊天。 项目简介 主要是通过做一个多人在线多房间群聊的小项目、来练手全栈技术的结合运用。 项目源码:chat-vue-node 主要技术: vue2全家桶 + socket....

    android_c 评论0 收藏0
  • 基于linux原生异步io创建的简易聊天程序

    摘要:分为两个独立的程序编译前先确定自己服务器的地址,比如想要在自己的下运行,先获取自己的地址,修改,里面的地址为自己的地址服务端编译运行客户端编译运行服务端先运行起来后,再启动客户端,可以在多态机器上启多个客户端,互相聊天 分为两个独立的程序编译前先确定自己服务器的地址,比如想要在自己的ubuntu下运行,先ip addr获取自己的ip地址,修改chat_server.c,chat_cli...

    xcold 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<