SoFunction
Updated on 2025-03-02

python implements multi-person chat room

This example shares the specific code of python implementing multi-person chat room for your reference. The specific content is as follows

1. Purpose

In the way of implementing small projects, we can consolidate the basic Python syntax and related knowledge I have learned before.

2. Related technologies

GUI Programming

2. Network programming

3. Multithreaded programming

4. Database programming

5. Simple export data to Excel table

3. Existing loopholes and shortcomings

1. Due to database encoding problems, Chinese cannot be used.

2. After the client is closed, its related threads still exist in the server's user thread queue, so the server will incorrectly transmit information to the closed client.

3. When the client initially logs in and loads the history record, the return key after each historical message will be lost. The solution is: add a time interval between loading two adjacent messages, but the effect is not good.

4. Source code

Server:

 # -*- coding: UTF-8 -*-

from socket import *
import time
import threading
import wx
import MySQLdb
import xlwt
from clientthread import ClientThread

class Server():
 def __init__(self,parent=None,id=-1,title='server',pos=,size=(500,300)):

 '''window'''
 .__init__(self,parent,id,title,pos,size=(400,470))
 pl = (self)
 con = ()
 subcon = ()
 sta = (pl , size=(133, 40),label='Start the server')
 end = (pl, size=(133, 40), label='Shut the server')
 hist = (pl,size=(133,40),label='Export chat history')
 (sta, 1, )
 (hist, 1, )
 (end, 1, )
 (subcon,1,wx.ALIGN_CENTRE|)
  = (pl, size=(400,250),style = wx.TE_MULTILINE|wx.TE_READONLY)
 (, 1, wx.ALIGN_CENTRE)
  = (pl, size=(400,100),style=wx.TE_MULTILINE)
 (, 1, wx.ALIGN_CENTRE)
 sub2 = ()
 clear = (pl, size=(200, 40), label='Clear')
 send = (pl, size=(200, 40), label='send')
 (clear, 1,  | )
 (send, 1,  | )
 (sub2, 1, wx.ALIGN_CENTRE)
 (con)
 '''window'''

 '''Binding'''
 (wx.EVT_BUTTON, , clear)
 (wx.EVT_BUTTON, , send)
 (wx.EVT_BUTTON, , sta)
 (wx.EVT_BUTTON, , end)
 (wx.EVT_BUTTON, , hist)
 '''Binding'''

 '''Server preparation'''
  = []
  = False
 addr = ('', 21567)
  = socket(AF_INET, SOCK_STREAM)
 (addr)
 (10)
 '''Server preparation'''

 '''Database preparation work for storing chat history'''
  = ('localhost', 'root', '123456', 'user_info')
  = ()
 ("select * from history order by time")
 ('')
 for data in (): #Load historical chat history ('%s said:\n%s\nwhen %s\n\n' % (data[0], data[2], data[1]))
 '''Database preparation work for storing chat history'''


 #Export chat history to EXCEl table def WriteToExcel(self,event):
 wbk = ()
 sheet = wbk.add_sheet('sheet 1')
 ("select * from history order by time")
 (0, 0, "User")
 (0, 1, "Datetime")
 (0, 5, "Message")
 index = 0
 for data in ():
 index = index + 1
 Time = '%s'%data[1] #Convert datetime into character form, otherwise writing directly to Excel will become a timestamp (index,0,data[0])
 (index,1,Time) #Written into EXCEL will become a timestamp (index,5,data[2])
 (r'D:\History_Dialog.xls')


 #Start the server's service thread def Start(self,event):
 if not :
 '''Start the service thread'''
  = True
 mainThread = (target=self.on_serving, args=())
 (True) # Solve the problem that the parent thread ends and the child thread continues to run ()
 '''Start the service thread'''

 #Shut down the server def Break(self,event):
  = False

 #SERVER MAIN LOOP def on_serving(self):
 print '...On serving...'
 while :
 UserSocket, UserAddr = ()
 username = (1024).decode(encoding='utf-8') #Receive username userthread = ClientThread(UserSocket, username,self)
 (userthread) #Add user thread to queue ()
 ()

 #Bind send button def SendMessage(self,event):
 if  and cmp((),''):
 data = ()
 ('Server',data,("%Y-%m-%d %H:%M:%S", ()))
 ('')


 # Send information to all clients (including themselves) and update to the database at the same time def AddText(self, source, data,Time):
 ("insert into history values(\"%s\",\"%s\",\"%s\")" % (source,Time,data)) #Double quotes have double quotes, bug: sentences cannot have double quotes, and Chinese ()
 sendData = '%s said:\n%s\nwhen %s\n' % (source,data,Time)
 ('%s\n'%sendData)
 for user in : #bug: The client is closed and still in the queue.  If the client is closed, how can I determine whether it has been closed on the server?  Does the client send a message to the server before closing? ((encoding='utf-8'))

 #Binding Clear Button def EditClear(self,event):
 ()


def main():
 app = (False)
 Server().Show()
 ()

if __name__ == '__main__':
 main()

Clientthread of the server:

# -*- coding: UTF-8 -*-

import threading
import time

class ClientThread():

 def __init__(self,UserSocket, Username,server):
 .__init__(self)
  = UserSocket
  = Username
  = server
 ()

 # Load historical chat history def Loadhist(self):
 ("select * from history order by time")
 for data in ():
 (0.6)  #Several messages are sent at the same time, which will cause the end Enter key to be lost, so there must be a time interval sendData = '%s said:\n%s\nwhen %s\n'%(data[0], data[2], data[1])
 ((encoding='utf-8'))


 #Method rewrite, thread entry def run(self):
 size = 1024
 while True:
 data = (size) #Unresolved: An error will be reported here after the client is disconnected (,(encoding='utf-8'),("%Y-%m-%d %H:%M:%S", ()))
 () #Not even executed here

Customer login interface Logframe:

# -*- coding: UTF-8 -*-

from socket import *
import wx
import MySQLdb
from client import Client

class LogFrame():
 def __init__(self,parent=None,id=-1,title='Login window',pos=,size=(500,300)):

 '''window'''
 .__init__(self,parent,id,title,pos,size=(400,280))
  = (self)
 con = ()
 subcon = (2,2,10,10)
 username = (, label="Username:",style=wx.ALIGN_LEFT)
 password = (, label="Password:",style=wx.ALIGN_LEFT)
 self.tc1 = (,size=(180,20))
 self.tc2 = (,size=(180,20),style=wx.TE_PASSWORD)
 (username,wx.TE_LEFT)
 (self.tc1,1,)
 (password)
 (self.tc2,1,)
 (subcon,1,wx.ALIGN_CENTER)
 subcon2 = (1,2,10,10)
 register = (,label='Register')
 login = (,label='Login')
 (register,1, )
 (login,1, )
 (subcon2,1,wx.ALIGN_CENTRE)
 (con)
 (wx.EVT_BUTTON,,register)
 (wx.EVT_BUTTON,,login)
 '''window'''
  = False
  = None

 #Connect to the server def ConnectToServer(self):
 if not :
 ADDR = ('localhost', 21567)
  = socket(AF_INET, SOCK_STREAM)
 try:
 (ADDR)
 (self.().encode(encoding='utf-8'))
  = True
 return True
 except Exception:
 return False
 else:
 return True

 #Log in def Login(self,event):
 if not ():
 err = (None, 'The server is not started', 'ERROR!', )
 ()
 ()
 else:
 username = self.()
 password = self.()
 db = ('localhost', 'root', '123456', 'user_info')
 cursor = ()
 ("select * from user_list where username='%s' and password='%s'"%(username,password))
 if not ():
 err = (None,'The user does not exist or the password is wrong','ERROR!',)
 ()
 else:
 ()
 Client(opSock=, username=username).Show()
 ()
 ()

 #register def Register(self,event):
 if not ():
 err = (None, 'The server is not started', 'ERROR!', )
 ()
 ()
 else:
 username = self.()
 password = self.()
 db = ('localhost', 'root', '123456', 'user_info')
 cursor = ()
 ("select * from user_list where username='%s'"%username)
 if not ():
 ("insert into user_list(username,password) values('%s','%s')"%(username,password))
 else:
 err = (None, 'The user already exists', 'ERROR!', )
 ()
 ()
 ()


def main():
 app = (False)
 LogFrame().Show()
 ()

if __name__ == '__main__':
 main()

Client:

#/usr/bin/env python
# -*- coding: UTF-8 -*-

import wx
import threading
from time import ctime

class Client():
 def __init__(self,opSock,username,parent=None,id=-1,title='Client',pos=,size=(500,300)):

 '''window'''
 .__init__(self,parent,id,title,pos,size=(400,470))
  = opSock
  = username
 pl = (self)
 con = ()
 subcon = ()
 sta = (pl, size=(200, 40),label='connect')
 end = (pl, size=(200, 40),label='disconnect')
 (sta, 1, |)
 (end, 1, |)
 (subcon,1,wx.ALIGN_CENTRE)
  = (pl, size=(400,250),style = wx.TE_MULTILINE|wx.TE_READONLY)
 (, 1, wx.ALIGN_CENTRE)
  = (pl, size=(400,100),style=wx.TE_MULTILINE)
 (, 1, wx.ALIGN_CENTRE)
 sub2 = ()
 clear = (pl, size=(200, 40), label='Clear')
 send = (pl, size=(200, 40), label='send')
 (clear, 1,  | )
 (send, 1,  | )
 (sub2, 1, wx.ALIGN_CENTRE)
 (con)
 '''window'''

 '''Binding'''
 (wx.EVT_BUTTON, , clear)
 (wx.EVT_BUTTON, , send)
 (wx.EVT_BUTTON, , sta)
 (wx.EVT_BUTTON, , end)
 '''Binding'''
  = False

 #Log in def Login(self,event):
 '''Client preparation'''
  = True
 t = (target=, args=())
 (True)
 ()
 '''Client preparation'''

 #quit def Logout(self,event):
  = False

 #Bind send button def Send(self,event):
 if  and cmp((),''):
 (().encode(encoding='utf-8'))
 ('')

 #Binding Clear Button def EditClear(self,event):
 ()

 #Receive client information (only one thread) def Receive(self):
 while :
 data = (1024).decode(encoding='utf-8')
 ('%s\n'%data)

For more exciting articles about python chat function, please click on the topic:Summary of python chat functions

The above is all the content of this article. I hope it will be helpful to everyone's study and I hope everyone will support me more.