Python基于socket套接字实现局域网聊天

3 篇文章 0 订阅
1 篇文章 0 订阅

只有管理员喊话功能没有添加,后续会继续更新!

服务端代码

import os,sys
from socket import *

# 用户登录函数
def do_login(sk,user,name,addr):
    # 判断用户是否在房间字典中
    if (name in user) or name == "管理员":
        data = "用户"+name+"已存在"
        sk.sendto(data.encode(),addr)
        return
    else:
        # 向客户端发送OK标志
        sk.sendto('OK'.encode(),addr)
        data = "用户"+name+"进入了聊天室"
        # 遍历字典向所有用户
        for i in user:
            sk.sendto(data.encode(),user[i])
        # 把用户加入字典
        user[name] = addr

# 转发用户聊天信息函数
def do_sends(sk,user,data,addr):
    for i in user:
        if user[i] != addr:
            sk.sendto(data.encode(),user[i])

# 用户退出房间
def do_exit(sk,user,data,addr):
    sk.sendto("quit".encode(),addr)
    del user[data]
    data = "用户"+data+"退出房间"
    for i in user:
        sk.sendto(data.encode(),user[i])




# 管理员喊话
def do_child(sk):
    print("我是子进程")


# 接受客户端请求
def do_parent(sk):
    user = {}
    print("我是父进程")
    while True:
        conn,addr = sk.recvfrom(1024)
        conn = conn.decode()
        connlist = [conn[0],conn[2:]]
        # 判断请求类型
        if connlist[0] == 'B' :
            # 用户登录
            do_login(sk,user,conn[2:],addr)
        elif connlist[0] == '&':
            # 转发用户来的消息
            do_sends(sk,user,conn[2:],addr)
            # 用户退出房间
        elif connlist[0] == 'Q':
            do_exit(sk,user,conn[2:],addr)




def main():
    # server address
    ADDR = ('0.0.0.0',8666)
    # 创建套接字
    sk = socket(AF_INET,SOCK_DGRAM)
    sk.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)
    sk.bind(ADDR)

    # 创建新的进程-->处理管理员喊话
    pid = os.fork()
    if pid < 0:
        sys.exit("创建进程失败")
    elif pid == 0:
        do_child(sk)
    else:
        do_parent(sk)


if __name__ == "__main__" :
    main()

客户端代码

import os,sys
from socket import *

# 登录聊天室
def login(sk,ADDR):
    while True:
        name = input("请输入姓名进入聊天室:")
        data = "B "+name
        # 发送登录请求
        sk.sendto(data.encode(),ADDR)
        # 等待服务器回复
        conn, addr = sk.recvfrom(1024)
        # 判断是否登录成功
        if conn.decode() == 'OK':
            print("您以进入聊天室")
            break
        else:
            # 返回不成功的原因
            print(conn.decode())
    return name

def do_sends(sk,name,ADDR):
    while True:
        data = input("发言>>")
        # 退出房间
        if data == "quit":
            # 发送Q+姓名标志给服务器
            sk.sendto(("Q "+name).encode(),ADDR)
            sys.exit("退出发言")
        data = "& "+name +">>:"+data 
        sk.sendto(data.encode(),ADDR)

def do_recvs(sk):
    while True:
        ret,ad = sk.recvfrom(1024)  
        if ret.decode() == 'quit':
            sys.exit("退出成功")
        print(ret.decode())

# 创建套接字,登录,登录成功则创建子进程
def main():
    if len(sys.argv)<3:
        print("输入错误")
        return
    HOST = sys.argv[1]
    PORT = int(sys.argv[2])
    ADDR = (HOST,PORT)
    # 创建UDP套接字
    sk = socket(AF_INET,SOCK_DGRAM)

    #登录聊天室,返回姓名
    name = login(sk,ADDR)

    # 创建一个新的线程负责发送信息
    pid = os.fork()
    if pid < 0:
        sys.exit("创建进程失败")
    elif pid == 0:
        # 发送信息
        do_sends(sk,name,ADDR)
    else:
        # 接受信息
        do_recvs(sk)


if __name__ == "__main__" :
    main()
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值