#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