Python online chat room (windows)

#server address
HOST = 'localhost'
#Server port
PORT = 9999
#Server pipeline address
PIPE_PORT=9998
#Data buffer size
BUFFERSIZE = 1024
#Server socket connection address
ADDR = HOST,PORT
#The server connects the keyboard to the server's pipe address
PIPE_ADDR = HOST,PIPE_PORT
#Default language selection
language = 'cn'

2. : international language configuration module (language.py)

The language.py module configures the internationalization configuration of the common prompt standard language

from settings import language

if language == 'en':
    administrator='Administrator'
    adm_close_chatroom = 'Chatroom closed by Administrator'
    user_enter_chatroom='entered the chatroom'
    user_quit_chatroom='quited the chatroom'
    username='username>'
    user_already_exists='username already exists'
    connect_to='connected to'
    connect_from='connected from'
    please_input_username='please input your username'
    out_three_times='input repeat username three times'
    welcome='welcome new user'
elif language =='cn':
    administrator='administrators'
    adm_close_chatroom = 'The administrator closed the chat room'
    user_enter_chatroom='Entered the chat room'
    user_quit_chatroom='Left the chat room'
    username='user name>'
    user_already_exists='User name already exists'
    connect_to='connection to'
    connect_from='Connection from'
    please_input_username='enter one user name'
    out_three_times='The user name entered is repeated more than three times'
    welcome='Welcome new users'

3. : prepare the chat room common module (common.py)

The common.py module provides two methods to create a server socket and a client socket

import os, sys
import socket
import shelve
import settings

#Create a socket server
def createserver(addr):
    #print('crate server',addr)
    server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR,1)
    server.bind(addr)
    server.listen()
    return server
    
#Create a socket client
def createclient(addr):
    #print('crate client',addr)
    client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    client.connect(addr)
    return client

4. : server module (server.py)

The server.py module creates a server socket for the client to connect. It mainly handles the broadcast information sent by the chat room administrator to all online users, and the chat content information forwarding function sent by the client online users

import os, sys
import socket
import select
import shelve
import settings
import language
import common
from multiprocessing import Process

#Chat room online user queue
users=[]
#Method for server processing and forwarding client chat information and administrator keyboard input content
def accept(server,pipe_server):
    'accept Server accept function'
    print('Enter listening')
    # Use the select method of the select module to realize IO multiplex listening and transmission
    rlist = [server, pipe_server]
    wlist = []
    xlist = []
    while True:
        rs, ws, xs = select.select(rlist, wlist, xlist)
        for r in rs:    
            if r is server:
                print('Server response client connection information=>',end='')
                conn,addr = server.accept()
                if(vlidate(conn)):
                    rlist.append(conn)
                    print(language.connect_from,addr)
                else:
                    conn.close()
            elif r is pipe_server:    ##Server side input
                print('Server pipeline response',end='(')
                conn,addr = pipe_server.accept()
                data = conn.recv(settings.BUFFERSIZE).decode()
                if data =='\n':
                    for c in rlist[2:]:
                        c.send(b'\n')
                        c.close()
                    server.close()
                    print(language.adm_close_chatroom,end="")
                    os._exit(0)
                else:
                    print(data.replace('\n',''),end=")\n")
                    data = language.administrator+":"+ data
                    for c in rlist[2:]:
                        c.send(data.encode())
            else:
                print("Server response client message",end='(')
                data = r.recv(settings.BUFFERSIZE).decode()
                #print(data.find(language.user_quit_chatroom)>=0)
                if not data or data.find(language.user_quit_chatroom)>=0:
                    r.close()
                    rlist.remove(r)
                print(data,end=")\n")
                for c in rlist[2:]:
                    c.send(data.encode())
            
#Verify that the user name of the login user already exists in the online user queue                  
def vlidate(conn):
    username = conn.recv(settings.BUFFERSIZE).decode()
    print('Login user name:',username,end="\n")
    if username in users:
        conn.send(language.user_already_exists.encode())
        return False
    else:
        users.append(username)
        conn.send((language.welcome+username).encode())
        return True

#Main program entry function                
def main():
    #Initialize server Socke
    server = common.createserver(settings.ADDR)

    #Process the server keyboard input broadcast command and close chat command
    pipe_server=common.createserver(settings.PIPE_ADDR)
    
    Create a multi thread to handle the forwarding of information sent by the client and the broadcast information sent by the administrator to online users
    p = Process(target=accept, args=(server, pipe_server))
    #p.daemon = True
    p.start()
    while True:
        try:
            data = sys.stdin.readline()
            #print(data)
        except KeyboardInterrupt:
            server.close()
            pipe_server.close()
            p.terminate()
            break
        if not data:
            continue
        elif data =='\n':
            #print('exit process')
            pipe_client=common.createclient(settings.PIPE_ADDR)
            #print(pipe_client)
            pipe_client.send(b'\n')
            pipe_client.close()
            os._exit(0)
        else:
            pipe_client=common.createclient(settings.PIPE_ADDR)
            pipe_client.send(data.encode())
            pipe_client.close()
        
if __name__ =='__main__':
    users= []
    main()

5. : client module (client.py)

The client.py module creates a client socket and connects to the server through the server address. It mainly handles the client login, the client sends chat information to the server, and accepts the broadcast sent by the server to itself and the information sent by other online users (forwarded by the server)

import os, sys
import socket
import select
import settings
import language
import common
from multiprocessing import Process

#Current user
curruser=''
#Process, receive and print the messages sent by the server to itself
def accept(client,curruser):
    rlist = [client]
    wlist = []
    elist = []
    while True:
        rs,ws,es = select.select(rlist,wlist,elist)
        for r in rs:
            if r is client:
                data = client.recv(settings.BUFFERSIZE)
                if data.decode() == '\n':
                    client.close()
                    print(language.adm_close_chatroom)
                    os.kill(os.getppid(), 9)
                    os._exit(0)
                    break
                else:
                    print(data.decode())
                    
#Process user login
def login():
    global curruser
    curruser = input(language.please_input_username)
    print(language.connect_to,settings.ADDR)

    client = common.createclient(settings.ADDR)
    client.send(curruser.encode())
    data  = client.recv(settings.BUFFERSIZE)
    if data.decode()==language.user_already_exists:
        print(language.user_already_exists)
        return (False)
    else:
        data = curruser+':'+language.user_enter_chatroom
        client.send(data.encode())
        return (True,client)
        
#Main program entry function   
def main():
    #pipe_server = common.createserver(common.CLI_PIPE_ADDR)
    
    count = 0
    isLogin = False
    while isLogin==False and count<3:
        isLogin = login()
        count=count+1
    if len(isLogin)==2:
        client = isLogin[1]
        print(curruser)
        p = Process(target=accept,args=(client,curruser))
        p.daemon = True
        p.start()    

        while True:
            try:
            	 #Handle client keyboard input and messages to be sent
                data = sys.stdin.readline()
            except KeyboardInterrupt:
                # If an exit / abort signal is encountered, send an exit message, close the socket, end the sub process and exit the program
                data = curruser+':'+user_quit_chatroom
                client.send(data.encode())
                client.close()
                pipe_client.close()
                p.terminate()
                break    
            if data=='\n':
                data = curruser+':'+language.user_quit_chatroom 
                client.send(data.encode())
                client.close()
                p.terminate()
                os._exit(0)
            else:
                data = curruser+':'+ (data.replace('\n',''))
                client.send(data.encode())
    else:
        print(language.out_three_times)
        
if __name__ == '__main__':
    main()    

6. : start operation
6.1 enter win+R on the keyboard, open the operation pop-up window, enter cmd, and then press enter to open the cmd command window

6.2. Use the cd command to enter the location of the source file, enter python server.py, and run the server

6.3. When the command window appears: enter listening, indicating that the server is started successfully

6.4 repeat the operations in 6.1 and 6.2, reopen a cmd command window, and enter the python client.py command to start the client

6.5. Enter the login user name as prompted, enter teamo here, and press enter
Client display

Server display

7. Complete function display
You can open more than one client and log in to the chat room, so as to better understand the whole operation and processing process of the chat room, as shown in the screenshot below

The administrator can send broadcast information to all online users, or enter directly without entering any information (close the whole chat room), or the client can enter directly without entering any information (exit the chat room)

So far, the whole chat room function has been introduced. Of course, at present, only public chat has been done, not one-to-one private chat. In addition, python GUI can be used to realize the chat room with form. Interested students can try it by themselves

Keywords: Python Windows udp

Added by Anzeo on Tue, 28 Sep 2021 10:55:17 +0300