客户端(可以并发运行)
import socket,threading,json
s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
# 服务器配置
sip="127.0.0.1"
sport=6666
def publicSend(ip,port,info):
while True:
info['news']=input("请输入要发送的内容:")
sendto(json.dumps(info),ip,port)
def theSend(ip,port):
while True:
data=input("请输入要发送的内容:")
s.sendto(data.encode("gbk"),(ip,int(port)))
def theReceive():
while True:
data=s.recvfrom(1024)
print("✨"*40+"\n数据来源 : %s:%s\n消息 : %s"%(data[1][0],data[1][1],data[0].decode("gbk")))
def sendto(data,ip,port):
s.sendto(data.encode("gbk"), (ip, port))
def recefrom():
data = s.recvfrom(1024)[0].decode("gbk")
print(data)
return data
def send(ip,port):
while True:
data=input("请输入要发送的内容:")
s.sendto(data.encode("gbk"),(ip,port))
def receive():
while True:
data=s.recvfrom(1024)
print(data)
print("✨"*40+"\n数据来源 : %s:%s\n消息 : %s"%(data[1][0],data[1][1],data[0].decode("gbk")))
if __name__ == '__main__':
name=''
pwd=''
flag=True
def login():
global name,pwd
name = input("用户名:")
pwd = input("密码:")
info = {
"alt": "登录", "name": name, "pwd": pwd
}
sendto(json.dumps(info), sip, sport)
if recefrom()== "登录失败!请检查账号密码!":
name=''
pwd=''
def privateChat():
global flag
if name == '':
print("未登录,请登录!")
warning=login()
if warning== "登录失败!请检查账号密码!":
return
else:
theName=input("请输入要私聊的用户:")
info={
"alt": "私聊", "name": name, "pwd": pwd,"data":theName
}
sendto(json.dumps(info),sip,sport)
theIp,thePort=s.recvfrom(1024)[0].decode("gbk").split(":")
threading.Thread(target=theReceive).start()
threading.Thread(target=theSend,args=(theIp,thePort)).start()
flag=False
def publicChat():
global flag
if name == '':
print("未登录,请登录!")
warning = login()
if warning == "登录失败!请检查账号密码!":
return
else:
print("-"*20+"已经进入公共聊天室,直接输入文本即可"+"-"*20)
threading.Thread(target=theReceive).start()
news = input()
info = {
"alt": "公聊", "name": name, "pwd": pwd, "news": news
}
sendto(json.dumps(info), sip, sport)
threading.Thread(target=publicSend, args=(sip, sport,info)).start()
flag = False
while True and flag:
choose=input("请选择: 1:注册 2:登录 3:查询在线 4:私聊 5:公聊 6 : 查询个人信息 :")
if choose=='1':
name=input("用户名:")
pwd=input("密码:")
info={
"alt":"注册","name":name,"pwd":pwd
}
sendto(json.dumps(info),sip,sport)
recefrom()
if choose=='2':
login()
if choose=='3':
info = { "alt": "查询在线"}
sendto(json.dumps(info),sip,sport)
all=s.recvfrom(1024)[0].decode("gbk").replace("[","").replace("]","").replace("'","").strip().split(",")
if all==[""]:print("无人在线!")
else:print("当前在线 %d 人:"%len(all))
for i in range(len(all)):
print(" "+all[i])
if choose=='4':
privateChat()
if choose=='5':
publicChat()
if choose=='6':
info = {"alt": "查询个人信息","name":name,"pwd":pwd}
sendto(json.dumps(info),sip,sport)
recefrom()
服务器(先运行这个,再运行客户端):
import socket,json,time
s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
# 服务器配置
s.bind(("",6666))
items=[]
def sendto(data,ip,port):
s.sendto(data.encode("gbk"), (ip, port))
# 接收消息并处理
def receive():
while True:
(info,(ip,port))=s.recvfrom(1024)
info=json.loads(info,encoding="gbk")
print(info)
# 登录功能
if info["alt"]=="登录":
panduan=False
for item in items:
if item['name']==info["name"] and item['pwd']==info['pwd']:
item['time'],item['ip'],item["port"]=time.time()+6*60,ip,port
sendto("登录成功!",ip,port)
panduan=True
break
if not panduan:
sendto("登录失败!请检查账号密码!",ip,port)
# 注册功能
if info["alt"]=="注册":
ctrl = False
for item in items:
if info["name"]==item["name"]:
sendto("该用户名已被注册",ip,port)
ctrl=True
break
if ctrl:continue
item={
"name":info["name"],"pwd":info["pwd"],"ip":ip,"port":port,"time":time.time()+6*60,"alt":""
}
items.append(item)
sendto("注册成功!",ip,port)
# 查询在线功能
if info["alt"]=="查询在线":
all=[]
for item in items:
if item['time']>time.time():
all.append(item['name'])
sendto(str(all),ip,port)
# 私聊
if info["alt"]=="私聊":
alt=False
for item in items:
if item['name']==info["name"] and item['pwd']==info['pwd']:
alt=True
shift=False
for i in items:
if info["data"]==i['name']:
sendto(str(i["ip"])+":"+str(i['port']),ip,port)
shift=True
break
if not shift:
sendto("私聊失败,不存在该用户",ip,port)
if not alt:
sendto("私聊失败,请登录")
# 公聊
if info['alt']=="公聊":
alt=False
for item in items:
# 检查登录
if item['name']==info["name"] and item['pwd']==info['pwd']:
alt=True
for i in items:
if i["time"]>time.time():
sendto("来自 %s 的公开消息: %s"%(info['name'],info['news']),i["ip"],i["port"])
if not alt:
sendto("公聊失败,请登录")
if info['alt']=="时间":
for item in items:
if item['name']==info["name"] and item['pwd']==info['pwd']:
for i in items:i["time"]=time.time()+6*60
# 查询个人信息
if info['alt']=='查询个人信息':
right=False
for item in items:
# 检查登录
if item['name'] == info["name"] and item['pwd'] == info['pwd']:
item['time']=time.time()+360
sendto("用户名:%s , 密码:%s , 你的IP:%s , 你的端口:%s , 在线时间戳:%s"%(item['name'],item['pwd'],item['ip'],item['port'],item['time']),ip,port)
right=True
if not right:
sendto("查询失败,请登录",ip,port)
receive()