Project Name: Multiplayer chat room
project structure:
client.py
server.py
settings.py
project ideas: the server receives client connections, the client sends information to the server, the server will send a message to all clients.
Project Implementation: the main process responsible for receiving keyboard input (sys.stdin.readline), using multiprocessing.Process function to create a process, in this process, using select two listening sockets, a socket is responsible for service and client receiving and sending messages between the other for keeping in touch with the main process.
# settings.py import os from socket import * from random import randint import shelve HOST = "127.0.0.1" # Server and client connection address SOCK_PORT = 4444 SOCK_ADDR = HOST, SOCK_PORT # Socket address server server.py file for pipe_server and pipe_client used SER_PIPE_PORT = 4321 SER_PIPE_ADDR = HOST, SER_PIPE_PORT # Socket address of the client client.py file for pipe_server and pipe_client use # as each client must have a different socket to make the role of the pipeline connection between the keyboard and play a network socket # port number to the next file record every run appears to ensure that no repeat IF not os.path.exists ( " ports.dat " ): f = shelve.open("ports") f["ports"] = [] f = shelve.open("ports") while True: n = randint(4500, 10000) if n not in f["ports"]: f['ports'].append(n) break f.close() CLI_PIPE_PORT = n CLI_PIPE_ADDR = HOST, CLI_PIPE_PORT # Buffer Size BUFFERSIZE = 1024 # Returns a TCP server socket DEF Server (addr): sock = socket, (AF_INET, SOCK_STREAM, and 0), sock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) sock.bind(addr) sock.listen(10) return sock # Returns a TCP client socket DEF Client (addr): sock = socket, (AF_INET, SOCK_STREAM, and 0), sock.connect(addr) return sock
# server.py import sys import shelve from socket import * from select import select from multiprocessing import Process from settings import * DEF the listen (sock_server, pipe_server): # the IO multiplexer: cyclic listening socket RLIST = [sock_server, pipe_server] wlist = [] xlist = [] Print ( " Waiting for connection ... " ) the while True: rs, ws, xs = select(rlist, wlist, xlist) for R & lt in RS: IF R & lt IS sock_server: # accept client connections Conn, addr = sock_server.accept () rlist.append(conn) elif R & lt IS pipe_server: # receive keyboard input sent to all clients Conn, addr = pipe_server.accept () data = conn.recv(BUFFERSIZE) data = bytes("管理员:", "UTF-8") + data for c in rlist[2:]: c.send(data) conn.close() the else : # receiving client information # sends the client information to the client to all the try : data = r.recv(BUFFERSIZE) except: r.close() rlist.remove(r) else: print(data.decode(), end="") for c in rlist[2:]: c.send(data) def clear_all(): f = shelve.open("ports") f['ports'].clear() f.close() IF __name__ == ' __main__ ' : # first ports contents are deleted clear_all () # Create two sockets # socket sock_server is a TCP server, responsible for service and client communication # socket pipe_server is a TCP server, but play a role in the pipeline, is responsible for receiving keyboard input sock_server = Server (SOCK_ADDR) pipe_server = server(SER_PIPE_ADDR) # Start a child process, listen function to perform the p-Process = (target = listen, args = (sock_server, pipe_server)) p.daemon = True p.start() # Cycle receive keyboard input the while True: the try : # from the standard input stream (keyboard) read a line of the Data = sys.stdin.readline () the except KeyboardInterrupt: # If you have exit / stop signal, the socket is closed, the end of child process , exit the program sock_server.close () pipe_server.close() p.terminate() clear_all() break IF not the Data: # If you get data from the keyboard is empty, continues to cycle the Continue the else : # get keyboard data, create client socket pipe_client, keyboard input to an pipe_server pipe_client = Client (SER_PIPE_ADDR) pipe_client.send(bytes(data, "UTF-8")) pipe_client.close()
# client.py import sys from socket import * from select import select from multiprocessing import Process from settings import * DEF Connect (sock_client, pipe_server, name): # the IO multiplexer: cyclic listening socket RLIST = [sock_client, pipe_server] wlist = [] xlist = [] while True: rs, ws, xs = select(rlist, wlist, xlist) for R & lt in RS: IF R & lt IS sock_client: # receiving server information Data = sock_client.recv (BUFFERSIZE) .decode () Print (Data, End = "" ) elif R & lt IS pipe_server: # accept keyboard input sent to the server Conn, addr = pipe_server.accept () data = conn.recv(BUFFERSIZE) data = bytes(name + ":", "UTF-8") + data sock_client.send(data) conn.close() def get_name(): return input("User name: ") IF the __name__ == ' __main__ ' : # Use get_name function to obtain a user name name = get_name () # Create two sockets # socket sock_client is a TCP client, the server and the client exchange # socket pipe_server is a TCP server, but play a role in the pipeline, is responsible for receiving keyboard input sock_client = Client (SOCK_ADDR) sock_client.send (bytes (name + " added to the chat room. \ n- " , " UTF-. 8 " )) pipe_server = server(CLI_PIPE_ADDR) # Start a child process, perform the function connect the p-Process = (target = connect, args = (sock_client, pipe_server, name)) p.daemon = True p.start() # Circulating receive keyboard input the while True: the try : # from the standard input stream (keyboard) reads a line Data = sys.stdin.readline () the except the KeyboardInterrupt: # if they quit / stop signal, transmitting information exits, the socket is closed ending child process exits the program sock_client.send (bytes (name + " out of the chat room. \ the n- " , " UTF-8 " )) sock_client.close() pipe_server.close() p.terminate() break IF not the Data: # If you get data from the keyboard is empty, continues to cycle the Continue the else : # get keyboard data, create client socket pipe_client, keyboard input to an pipe_server pipe_client = Client (CLI_PIPE_ADDR) pipe_client.send(bytes(data, "UTF-8")) pipe_client.close()