Python for network multiplayer chat rooms, web development actually so simple

Online multiplayer chat room

File Structure:

  ChatRoom
  ├── client.py # client code
  ├── language.py # language files
  ├── server.py # server code
  └── settings.py # settings file

  0 directories, 4 files

Using the Module:

  • the
  • sys
  • socket
  • select

Ideas:

  • settings.py, defined HOST, PORT, ADDR, buffersize, language, curuser variables.
  • server.py, server code module using the select-implemented method IO multiplexer select input and a client listening sys.stdin connectivity for communicating with a client, the client receives information from the bulk to each client.
  • client.py, client code, use the same IO multiplexer while listening client receives information and sys.stdin input information, communicate with the server to achieve, indirectly chat group with other clients.
  • language.py, language file support Chinese and English.

Code:

settings.py

# settings.py

HOST = '0.0.0.0'      # 主机名
PORT = 5555            # 端口号
buffersize = 1024    # 缓冲大小
ADDR = HOST, PORT    # 地址

languages = ['cn', 'en']      # 'cn' -> 中文
language = 'cn'                # 'en' -> 英文

curuser = ''  # 当前用户

language.py


# language.py

from settings import language

if language == 'en':
    administrator = 'Administrator'
    txt_administrator_close_chatroom = 'Chatroom closed by Administrator.'
    txt_uesr_enter_chatroom = 'entered the chatroom.'
    txt_user_quit_chatroom = 'quited the chatroom.'
    txt_username = 'username> '
    txt_user_already_exists = 'Username already exists!'
    txt_connect_to = 'Connected to'
    txt_connect_from = 'Connected from'
elif language == 'cn':
    administrator = '管理员'
    txt_administrator_close_chatroom = '管理员关闭了聊天室。'
    txt_uesr_enter_chatroom = '进入了聊天室。'
    txt_user_quit_chatroom = '退出了聊天室。'
    txt_username = '用户名> '
    txt_user_already_exists = '用户名已存在。'
    txt_connect_to = '连接到'
    txt_connect_from = '连接从'

server.py

# server.py

# 导入系统模块
import os, sys
# 导入网络编程(传输层)模块
from socket import *
# IO多路复用模块
from select import select
# 设置模块
from settings import *
# 语言模块
from language import *

def main():
    'main 主函数'
    server = socket(AF_INET, SOCK_STREAM)  # 建立TCP套接字
    server.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)  # 设置端口可立即重用
    server.bind(ADDR)  # 绑定地址
    server.listen()  # 监听

    # 接收函数
    accept(server)

def accept(server):
    'accept 服务器接受函数'

    # 使用select模块的select方法实现IO多路复用监听传输
    rlist = [server, sys.stdin]
    wlist = []
    xlist = []

    while True:
        rs, ws, xs = select(rlist, wlist, xlist)

        for r in rs:
            if r is server:
                # 服务器接受客户端连接
                conn, addr = server.accept()
                # 调用validate函数检查用户名
                if validate(conn):
                    # 将客户端套接字添加到rlist中以监听
                    rlist.append(conn)
                    # 如果用户名注册成功
                    print(txt_connect_from, addr)
                else:
                    conn.close()
            elif r is sys.stdin:
                # 服务器向所有客户端发送系统(管理员)消息
                data = sys.stdin.readline()
                if data == '\n':
                    # 如果服务器输入回车,则退出
                    for c in rlist[2:]:
                        c.send(b'\n')
                        c.close()
                    server.close()
                    print(txt_administrator_close_chatroom)
                    os._exit(0)
                else:
                    # 如果服务器输入正常语句,通知所有客户端
                    data = administrator + ': ' + data
                    for c in rlist[2:]:
                        c.send(data.encode())
            else:
                # 服务器接受客户端的消息并转发给所有客户端
                data = r.recv(buffersize)
                if not data:
                    # 关闭客户端
                    r.close()
                    rlist.remove(r)
                else:
                    # 转发信息给其他客户端
                    print(data.decode(), end='')
                    for c in rlist[2:]:
                        if c is not r:
                            c.send(data)

def validate(client):
    '检验用户名 validate username'
    name = client.recv(buffersize).decode()
    # print(name.decode())
    # print(users)
    if name in users:
        client.send(b'Username already exists!')
        return False
    else:
        users.append(name)
        client.send(b'Welcome!')
        return True

if __name__ == '__main__':
    # 全局变量,管理用户信息
    users = []

    # 主函数
    main()

client.py

# client.py

# 导入系统模块
import os, sys
# 导入网络编程(传输层)模块
from socket import *
# IO多路复用模块
from select import select
# 设置模块
from settings import *
# 语言模块
from language import *

def main():
    'main 主函数'
    client = socket(AF_INET, SOCK_STREAM)  # 建立TCP套接字

    # 登录函数
    if login(client):
        # 连接函数
        connect(client)

def connect(client):
    'connect 客户端连接函数'

    # 使用select模块的select方法实现IO多路复用监听传输
    rlist = [client, sys.stdin]
    wlist = []
    xlist = []

    while True:
        rs, ws, xs = select(rlist, wlist, xlist)

        for r in rs:
            if r is client:
                # 接受服务器发来的消息
                data = client.recv(buffersize)
                if data.decode() == '\n':
                    # 如果消息为回车,聊天室关闭
                    client.close()
                    print(txt_administrator_close_chatroom)
                    os._exit(0)
                else:
                    # 打印接收到的信息
                    print(data.decode(), end='')
            elif r is sys.stdin:
                # 发送消息给服务器
                data = sys.stdin.readline()
                if data == '\n':
                    # 如果回车,发送退出消息,关闭客户端,退出聊天室
                    data = curuser + ': ' + txt_user_quit_chatroom + '\n'
                    client.send(data.encode())
                    client.close()
                    os._exit(0)
                else:
                    # 发信息给服务器
                    data = curuser + ': ' + data
                    client.send(data.encode())

def login(client):
    '登录函数 login'
    # 使用全局变量管理用户
    # 先让客户端输入姓名
    global curuser
    curuser = input(txt_username)
    # 再连接到服务器,传送用户名以检验
    client.connect(ADDR)  # 连接到服务器地址
    print(txt_connect_to, ADDR)
    client.send(curuser.encode())
    data = client.recv(buffersize)
    if data.decode() == 'Username already exists!':
        # 如果用户名已经存在,要求重新输入
        print(txt_user_already_exists)
        return False
    else:
        # 发送信息给服务器,告知服务器用户进入聊天室
        # -*- 因为监听传输的是sys.stdin.readline(),所以必须在最后添加换行符,以便清除阻塞 -*-
        data = curuser + ': ' + txt_uesr_enter_chatroom + '\n'
        client.send(data.encode())
        return True

if __name__ == '__main__':
    main()

Run shot:

Python for network multiplayer chat rooms, web development actually so simple

If you are still confused in the programming world, you can join us to learn Python buckle qun: 784758214, look at how seniors are learning. Exchange of experience. From basic web development python script to, reptiles, django, data mining and other projects to combat zero-based data are finishing. Given to every little python partner! Share some learning methods and need to pay attention to small details, click on Join us python learner gathering

to sum up:

  • Before playing the code, make sure to plan, write roughly approximate route of the project.
  • Realization of the project from the beginning of the most basic foundations, like a chat room to achieve more than you must first establish a network between the server and the client starts, but can not start from the surface. For example, if to do a graphical interface application online multiplayer chat room, absolutely can not go to write achieve graphical interface, even if the final realization of how good-looking graphical interface, network communication can not be achieved if dry and white.
  • For projects go wrong point, you should pay more notes, easy to read later, find useful knowledge, you can copy the URL in the Internet down, written into the project document, to facilitate future contingencies.

Guess you like

Origin blog.51cto.com/14510224/2437132