Python オンライン チャット ルーム (Windows)

Python オンライン チャット ルーム (Windows)


1. システムパラメータ設定モジュール (settings.py) を準備する

#服务器地址
HOST = 'localhost'
#服务器端口
PORT = 9999
#服务器管道地址
PIPE_PORT=9998
#数据缓冲大小
BUFFERSIZE = 1024
#服务器端socket连接地址
ADDR = HOST,PORT
#服务端连接键盘和服务端的管道地址
PIPE_ADDR = HOST,PIPE_PORT
#默认语言选择
language = 'cn'

2.: 国際化言語設定モジュール( language.py )

language.py モジュールは、パブリック プロンプトの標準言語の国際化構成を構成します。

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='管理员'
    adm_close_chatroom = '管理员关闭了聊天室'
    user_enter_chatroom='进入了聊天室'
    user_quit_chatroom='离开了聊天室'
    username='用户名>'
    user_already_exists='用户名已经存在'
    connect_to='连接到'
    connect_from='连接来自于'
    please_input_username='请输入用户名'
    out_three_times='输入用户名重复超过三次'
    welcome='欢迎新用户'

3. チャットルーム共通モジュール(common.py)を準備する

common.py モジュールは、サーバー ソケットとクライアント ソケットを作成する 2 つのメソッドを提供します。

import os, sys
import socket
import shelve
import settings

#创建一个socket服务端
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
    
#创建一个socket客户端
def createclient(addr):
    #print('crate client',addr)
    client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    client.connect(addr)
    return client

4.: サーバーモジュール(server.py)

server.py モジュールは、クライアントが接続するためのサーバー ソケットを作成し、主にチャット ルーム管理者がすべてのオンライン ユーザーにブロードキャスト情報を送信する処理と、クライアントのオンライン ユーザーが送信したチャット コンテンツ情報の転送機能を処理します。

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

#聊天室在线用户队列
users=[]
#服务端处理转发客户端聊天信息以及管理员键盘输入内容的方法
def accept(server,pipe_server):
    'accept 服务器接受函数'
    print('进入监听')
    # 使用select模块的select方法实现IO多路复用监听传输
    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('服务器响应客户端连接信息=>',end='')
                conn,addr = server.accept()
                if(vlidate(conn)):
                    rlist.append(conn)
                    print(language.connect_from,addr)
                else:
                    conn.close()
            elif r is pipe_server:    ##服务器端输入内容
                print('服务器管道响应',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("服务器响应客户端消息",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())
            
#校验登录用户的用户名是否已经存在于在线用户队列中                  
def vlidate(conn):
    username = conn.recv(settings.BUFFERSIZE).decode()
    print('登录用户名:',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

#主程序入口函数                
def main():
    #初始化服务器Socke
    server = common.createserver(settings.ADDR)

    #处理服务器键盘输入广播命令以及关闭聊天室命令
    pipe_server=common.createserver(settings.PIPE_ADDR)
    
    创建多线程,用来处理客户端发送信息的转发以及管理员向在线用户发送的广播信息
    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('退出流程')
            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.py)

client.py モジュールはクライアント ソケットを作成し、サーバー アドレスを介してサーバーに接続します。主にクライアントのログインを処理し、クライアントはチャット情報をサーバーに送信し、サーバーから自分自身に送信されたブロードキャストと他のオンライン ユーザーから送信された情報を受け取ります。 (サーバーによって転送されます)

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

#当前用户
curruser=''
#处理接收并打印服务端向自己发送的消息
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())
                    
#处理用户登录
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)
        
#主程序入口函数   
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:
            	 #处理客户端键盘输入并需要发送的消息
                data = sys.stdin.readline()
            except KeyboardInterrupt:
                # 如果遇到退出/中止信号,发送退出信息,关闭套接字,结束子进程,退出程序
                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. 6.1 を起動して実行し
、キーボードで win+R を入力し、実行中のポップアップ ウィンドウを開き、「cmd」と入力して Enter キーを押して cmd コマンド ウィンドウを開きます。 6.2、cd コマンドを使用してソース ファイルの場所を入力します
ここに画像の説明を挿入
。 python server.py と入力し、サーバー
ここに画像の説明を挿入
6.3 を実行します。コマンド ウィンドウが表示されたら、監視を開始します。これは、サーバーが正常に
ここに画像の説明を挿入
6.4 を開始したことを意味します。6.1、6.2 を繰り返して cmd コマンド ウィンドウを再度開き、python client.py コマンドを入力します。クライアント
ここに画像の説明を挿入
6.5 を起動するには、プロンプトに従ってログイン ユーザー名を入力します。 ここで「teamo」と入力し、Enter キーを押します。
クライアントに次の画面が表示されます
ここに画像の説明を挿入
。 サーバーに次の画面が表示されます。
ここに画像の説明を挿入

7. 完全な機能表示
もう 1 つのクライアントを開いてチャット ルームにログインすると、チャット ルームの全体的な操作と処理プロセスをより明確に理解できます。下のスクリーンショットに示すように、管理者はブロードキャスト情報を送信できます
ここに画像の説明を挿入
。すべてのオンライン ユーザーに送信するか、何も入力できません 直接情報を入力する (チャット ルーム全体を閉じる) か、クライアントは情報を入力せずに Enter を押す (チャット ルームを終了する) こともできます
ここに画像の説明を挿入
。これで機能が完成しました もちろん、まだ公開チャットのみでペアリングなどは行っていません 自分のプライベートチャット、Python GUIを使ってフォーム付きのチャットルームを実装できます 興味のある学生は自分で試してみてください

おすすめ

転載: blog.csdn.net/teamo_m/article/details/120529334