1. 程式人生 > >Python網路程式設計---實現聊天室

Python網路程式設計---實現聊天室

寫一個聊天室
要求:
1.進入聊天室需要輸入姓名,姓名不能重複
2.有人進入聊天室會想其他人傳送通知,xxx 進入了聊天室
3.一個人發訊息,其他人會收到訊息
xxx 說:xxxx
4.某人退出聊天室,其他人也會收到通知
xxx 退出了聊天室
5.管理員喊話功能

-基於udp的網路傳輸

  • 服務端:

#!/usr/bin/env python3
#coding=utf-8
'''
name:xx
email:xxx
data:2018/9/11
introduce:Chatroom server
env:python3.5
'''
from socket import
* import os,sys #登入判斷 def do_login(s,user,name,addr): if (name in user) or name == '管理員': s.sendto('\n該使用者已存在'.encode(),addr) return s.sendto(b'OK',addr) #通知其他人 msg='\n歡迎%s進入聊天室' % name for i in user: s.sendto(msg.encode(),user[i]) #插入使用者 user[name] = addr #訊息傳送
def do_chat(s,user,name,text): msg = '\n%s說:%s' % (name,text) for i in user: if i !=name: #退出聊天室 def do_quit(s,user,name): msg = '\n' +name + '退出了聊天室' for i in user: if i == name: s.sendto(b'EXIT',user[i]) else: s.sendto(msg.encode(),user[i]) #從字典中刪除使用者
del user[name] #接收客戶端請求 def do_parent(s): #儲存結構,{'zhangsan':('127.0.0.1',9999)} user = {} while True: msg,addr = s.recvfrom(1024) msgList = msg.decode().split(' ') #區分請求型別 if msgList[0] == 'L': do_login(s,user,msgList[1],addr) elif msgList[0] == 'C': do_chat(s,user,msgList[1],' '.join(msgList[2:])) elif msgList[0] == 'Q': do_quit(s,user,msgList[1]) #做管理員喊話 def do_child(s,addr): while True: msg = input('管理員訊息:') msg = 'C 管理員 ' + msg s.sendto(msg.encode(),addr) #建立網路,建立程序,呼叫功能函式 def main(): #定義server address ADDR = ('0.0.0.0',8888) #建立套接字 s = socket(AF_INET,SOCK_DGRAM) s.setsockopt(SOL_SOCKET,SO_REUSEADDR,1) s.bind(ADDR) #建立一個單獨的程序處理管理員喊話功能 pid = os.fork() if pid < 0: sys.exit('建立程序失敗') elif pid == 0: do_child(s,ADDR) else: do_parent(s) if __name__ == '__main__': main()
  • 客戶端
from socket import *
import os,sys

#傳送訊息
def send_msg(s,name,addr):
    while True:
        text = input('發言:')
        #如果輸入quit表示退出
        if text.strip() == 'quit':
            msg = 'Q ' + name
            s.sendto(msg.encode(),addr)
            sys.exit('退出聊天室')
        msg = 'C %s %s' % (name,text)
        s.sendto(msg.encode(),addr)

#接收訊息
def recv_msg(s):
    while True:
        data,addr = s.recvfrom(2048)
        if data.decode() == 'EXIT':
            sys.exit(0)
        print(data.decode() + '\n發言:',end='')

#建立套接字,登入,如果登入成功,建立子程序
def main():
    #從命令列獲取服務端地址
    if len(sys.argv) < 3:
        print('argv is error')
        return
    HOST = sys.argv[1]
    PORT = int(sys.argv[2])
    ADDR = (HOST,PORT)

    #建立套接字
    s = socket(AF_INET,SOCK_DGRAM)

    while True:
        name = input('請輸入姓名:')
        msg = 'L ' + name
        #傳送登入請求
        s.sendto(msg.encode(),ADDR)
        #等待伺服器回覆
        data,addr = s.recvfrom(1024)
        if data.decode() == 'OK':
            print('您已進入聊天室')
            break
        else:
            #不成功伺服器會回覆不允許登入的原因
            print(data.decode())

    #建立父子程序
    pid = os.fork()
    if pid < 0:
        sys.exit('建立子程序失敗')
    elif pid == 0:
        send_msg(s,name,ADDR)
    else:
        recv_msg(s)

if __name__ == '__main__':
    main() 

總結:
1、聊天室通過服務端轉發訊息給所有客戶端來實現群聊的功能。
2、採用基於udp的網路傳輸來完成。
3、採用多程序程式設計,父子程序分別處理訊息的接收和傳送