基於python的聊天室

2020-08-09 01:00:47

基於python的聊天室

1.server

server用於中轉訊息,如果想要實現真實的聊天室,必須將server的ip設定爲雲服務,或者公網ip


from socket import *
from select import select

def main():
    'main 主函數'
    server = socket(AF_INET, SOCK_STREAM)  # 建立TCP通訊端
    server.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)  # 設定埠可立即重用
    ADDR = '127.0.0.1', 5555
    server.bind(ADDR)  # 系結地址
    server.listen()  # 監聽
    # 接收函數
    accept(server)


def accept(server):
    'accept 伺服器接受函數'
    # 使用select模組的select方法實現IO多路複用監聽傳輸
    rlist = [server]
    wlist = []
    xlist = []

    while True:
        rs, ws, xs = select(rlist, wlist, xlist)
        for r in rs:
            # 伺服器接受用戶端連線
            if r is server:
                try:
                    conn, addr = server.accept()
                    welcome(conn)
                    # 將用戶端通訊端新增到rlist中以監聽
                    rlist.append(conn)
                    print("鏈接從:", addr)
                except:
                    pass

            else: # 伺服器接受用戶端的訊息並轉發給所有用戶端
                try:
                    data = r.recv(1024)
                    # 轉發資訊給其他用戶端
                    data = b'\n' + data + b'\n'
                    print(data.decode(), end='')
                    for c in rlist[1:]:
                        if c is not r:
                            c.send(data)
                except:
                    rlist.remove(r)

def welcome(client):
    client.send(b'Welcome! \n')
    return True

if __name__ == '__main__':
    # 主函數
    main()

2. client1

import os, sys
import threading
from socket import *
from select import select

def main():
    'main 主函數'
    client = socket(AF_INET, SOCK_STREAM)  # 建立TCP通訊端
    if login(client):
        t_recv = threading.Thread(target=recv, args=(client,))
        t_send = threading.Thread(target=send_msg, args=(client,))
        t_recv.start()
        t_send.start()

def send_msg(client):
    while True:
        send_data = input("請輸入要發送的數據:")
        send_data = username + ":" +send_data
        client.send(send_data.encode("utf-8"))

def recv(client):
    # 使用select模組的select方法實現IO多路複用監聽傳輸
    rlist = [client]
    wlist = []
    xlist = []

    while True:
        rs, ws, xs = select(rlist, wlist, xlist)
        for r in rs:
            if r is client:
                # 接受伺服器發來的訊息
                data = client.recv(1024)
                if data.decode() == '\n':
                    # 如果訊息爲回車,聊天室關閉
                    client.close()
                    os._exit(0)
                else:
                    # 列印接收到的資訊
                    print(data.decode(), end='')

def login(client):
    '登錄函數 login'
    curuser = input('輸入名稱>')
    global username
    username = curuser
    ADDR = '127.0.0.1', 5555
    client.connect(ADDR)  # 連線到伺服器地址
    data = curuser + ': ' + "進入房間"
    client.send(data.encode())
    return True

if __name__ == '__main__':
    main()

3.client2

import os, sys
import threading
from socket import *
from select import select

def main():
    'main 主函數'
    client = socket(AF_INET, SOCK_STREAM)  # 建立TCP通訊端
    if login(client):
        t_recv = threading.Thread(target=recv, args=(client,))
        t_send = threading.Thread(target=send_msg, args=(client,))
        t_recv.start()
        t_send.start()

def send_msg(client):
    while True:
        send_data = input("請輸入要發送的數據:")
        send_data = username + ":" +send_data
        client.send(send_data.encode("utf-8"))

def recv(client):
    # 使用select模組的select方法實現IO多路複用監聽傳輸
    rlist = [client]
    wlist = []
    xlist = []

    while True:
        rs, ws, xs = select(rlist, wlist, xlist)
        for r in rs:
            if r is client:
                # 接受伺服器發來的訊息
                data = client.recv(1024)
                if data.decode() == '\n':
                    # 如果訊息爲回車,聊天室關閉
                    client.close()
                    os._exit(0)
                else:
                    # 列印接收到的資訊
                    print(data.decode(), end='')

def login(client):
    '登錄函數 login'
    curuser = input('輸入名稱>')
    global username
    username = curuser
    ADDR = '127.0.0.1', 5555
    client.connect(ADDR)  # 連線到伺服器地址
    data = curuser + ': ' + "進入房間"
    client.send(data.encode())
    return True

if __name__ == '__main__':
    main()