# 服务端
PS G:\BaiduNetdiskDownload\VS2019Space\PythonApplication1> python
Python 3.11.4(tags/v3.11.4:d2340ef, Jun 72023,05:45:37)[MSC v.193464 bit (AMD64)] on win32
Type "help","copyright","credits"or"license"for more information.>>>from Jbjn import SocketSv
>>> a=SocketSv.SocketSv()>>> a.ServerStart()
服务端启动
欢迎('127.0.0.1',51885)
服务端收到: This is a good time.
服务端发送:Yes,Welcome to Chat.
服务端收到: Oh,It's so cool.# 客户端>>>from Jbjn import SocketSv
>>> b=SocketSv.SocketSv()>>> b.ClientStart()
客户端启动
('127.0.0.1',18080)
客户端发送:This is a good time.
客户端收到: Yes,Welcome to Chat.
客户端发送:Oh,It's so cool.
以上只能实现单一通信,发送后必须等待接收,实现群聊的需要使用到多线程
使用UDP通信
创建群聊服务端
# ServerMany服务器defserverMany(self,ip='127.0.0.1',port=9999):try:
s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)# 创建socket对象 数据报式Socket
addr=(ip,port)
s.bind(addr)# 绑定地址和端口print('服务端启动,地址:',addr)
user={}# 存放字典{addr:name}whileTrue:try:
data,addr=s.recvfrom(1024)# 等待接受客户端消息存放在2个变量data和addr里ifnot addr in user:# 如果addr不在user字典里则执行以下代码for address in user:# 从user遍历数据出来address
s.sendto(data+'Enter ChattingRoom...'.encode('utf-8'),address)# 发送user字典的data和address到客户端
user[addr]=data.decode('utf-8')# 接受的消息解码成utf-8并存在字典user里,键名定义为addrcontinue# 如果addr在user字典里,跳过本次循环if'EXIT'.lower()in data.decode('utf-8'):# 如果EXIT在发送的data里
name=user[addr]# user字典addr键对应的值赋值给变量name
user.pop(addr)# 删除user里的addrfor address in user:# 从user取出address
s.sendto((name +'离开了ChattingRoom...').encode(),address)# 发送name和address到客户端else:print(f'{data.decode("utf-8")} from {addr[0]}:{addr[1]}')for address in user:# 从user遍历出addressif address!=addr:# address不等于addr时间执行下面的代码
s.sendto(data,address)# 发送data和address到客户端except ConnectionResetError:print('服务端异常')except Exception as e:
s.close()print(str(e))# 创建客户端;
name='username'defrecv(self,sock,addr):'''
一个UDP连接在接收消息之前必须要让系统知道所占端口
也就是需要send一次,否则win下会报错
'''
sock.sendto(name.encode('utf-8'),addr)whileTrue:
data=sock.recv(1024)if data:print(data.decode('utf-8'))defsend(self,sock,addr):'''
发送数据的方法
参数:
sock:定义一个实例化socket对象
server:传递的服务器IP和端口
'''whileTrue:
string=input('正在输入:')
message=name+':'+string
if message:
data=message.encode('utf-8')
sock.sendto(data,addr)if string.lower()=='EXIT'.lower():breakdefmain(self,ip='127.0.0.1',port=9999):import threading
global name
name=input('请输入你的名称:')'''
主函数执行方法,通过多线程来实现多个客户端之间的通信
'''
s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
server=(ip,port)
tr=threading.Thread(target=self.recv,args=(s,server),daemon=True)
ts=threading.Thread(target=self.send,args=(s,server))
tr.start()
ts.start()
tr.join()
ts.join()
s.close()passpass
main()
G:\BaiduNetdiskDownload\VS2019Space\PythonApplication1>python
Python 3.11.4(tags/v3.11.4:d2340ef, Jun 72023,05:45:37)[MSC v.193464 bit (AMD64)] on win32
Type "help","copyright","credits"or"license"for more information.>>>from Jbjn import SocketSv
>>> a=SocketSv.SocketSv()>>> a.serverMany()
服务端启动,地址:('127.0.0.1',9999)
Mr.Bai:xiawuhao! from127.0.0.1:60931
Mr.Li:Hello! from127.0.0.1:50487
Mr.Bai:Who are you? from127.0.0.1:60931
Mr.Li:I'm Mr.Li,And you? from127.0.0.1:50487
Mr.Bai:I'm Mr.Bai.Nice to meet you.from127.0.0.1:60931
Miss.Yun:Can I see history messages? from127.0.0.1:56873
Mr.Bai:Yes,I think you can.from127.0.0.1:60931
Mr.Li:It's cool.from127.0.0.1:50487
Miss.Yun:It's time to go home.from127.0.0.1:56873
Mr.Li:Let's go.from127.0.0.1:50487
Mr.Bai:Qiu dou ma dai.from127.0.0.1:60931