在之前的时候,我们解决了:
服务器可以链接多个设备
循环聊天
校验用户输入内容
但是呢,我们发现其实不能进行消息发送给所有人,或者消息发送给其他人,那么如何来实现呢,今天我们来带领大家看下。这里要有这样的一个思路
1.存储不一样用户得soket的信息
2.针对不一样消息发送给不一样得用户
存储soket的信息,在这里,演示用,用常用的字典来实现,不同的消息发送给不同的用户,就是定义消息的类型选择不同的发送方式。先来解决第一个,存储用户的信息
username={}
def reuqets(sock):
global username
user_name = ''
while True:
try:
# sock就是双向通道,addr就是客户端地址
# 5.服务用户 等待客户端发消息
data = sock.recv(1024).decode('utf-8') # 接受客户端发送过来的信息 1024字节
if len(data) == 0:
break
if data=='exit':
username.pop(user_name)
sock.close()
if str(data).startswith("login"):
username[str(data).split("login")[-1]]=sock
user_name=str(data).split("login")[-1]
send_all("欢迎:"+str(data).split("login")[-1])
print(data)
send_orther(data,user_name)
用username得字典来存储。接下来,有两个方法 一个是发送给全部的,一个发送给了除某个用户之外的用户,那么看下如何来实现呢
def send_all(msg):
print("开始给所有的用户发送消息")
now=datetime.datetime.now()
format_str = now.strftime("%Y-%m-%d %H:%M:%S")
for item in username.values():
try:
item.send((format_str+msg).encode('utf-8'))
except Exception as e:
print(e)
def send_orther(msg,name):
print("开始给其他用户发送消息")
for item in username.keys():
if item!=name:
try:
username[item].send((name+"发送消息:"+msg).encode("utf-8"))
except Exception as e:
print(e)
其实很简单的实现方式,即不增加了一个参数,这个参数就是区分是否发给所有的,也可以将这个方法编写出来一个方法,这里为了演示,用了两个方式。那么客户端接收呢
这里客户端要实现一直在发送,服务端一直在转发,客户端在接受,在发送,一个死循环。那么如何来实现呢,接收我们单独放在一个线程中,不耽误主线程。看下如何来实现的
import socket
# 1.生成socket对象指定类型和协议
import threading
client = socket.socket()
# 2.通过服务端的地址链接服务端
client.connect(('127.0.0.1', 8013))
msg = input("请输入用户名注册服务:").strip()
client.send(("login" + msg).encode("utf8"))
# 3.直接给服务端发送消息
def msg_recv():
"""
接收数据
"""
while True:
try:
data = client.recv(1024).decode("utf-8")
if data!="":
print(data+"\n")
except:
pass
reve = threading.Thread(target=msg_recv)
reve.start()
while True:
msg = input('向服务端发送的消息:').strip()
if len(msg) == 0:
print('输入不能为空')
else:
try:
client.send(msg.encode("utf-8"))
except:
pass
看下最后的效果
到这里,关于socket分享就结束了。