前言
笔者最近也捡了捡n多年前学过的一点python基础,接触了一些socket编程,也参考了一些其他大佬的博客。
看见一个比较有趣的题目:用socket制作一个聊天室,于是自己也试着做了一下。
参考博客:https://blog.csdn.net/exmlyshy/article/details/85320971
在我的代码中我参考了上述博客的思路(客户端的脚本基本没什么改动),然后我在服务端的代码中加入了聊天记录的功能(通过写入文件),另外还有显示在线用户的功能。
程序
服务端
import socket
import time
svrsocket
= socket
.socket
(socket
.AF_INET
,socket
.SOCK_DGRAM
)
svrsocket
.bind
(('',8080))
users
= {}
def send_record(msg
):
'''
接收一个字符串
打印并传递给write2file和broadcast
通过该方法可在服务器和用户上看见用户进入/离开聊天室以及用户聊天信息
同时将上述信息写入文件(通过write2file)
'''
print(msg
)
write2file
(msg
)
broadcast
(msg
)
def write2file(string
):
'''
接收一个字符串
可将字符串作为单独的一行追加到文件末尾
用于将聊天信息记录到文件中
'''
file = open('/root/python/chat_history.txt','a')
file.write
(string
+"\n")
file.close
()
def broadcast(msg
):
'''
在套接字中广播(给每个用户都发送msg)
把每个用户发送的信息都发送给其他用户
'''
for address
in users
:
svrsocket
.sendto
(msg
.encode
(), address
)
while True:
try:
user_data
, user_addr
= svrsocket
.recvfrom
(1024)
if not user_addr
in users
:
enter_msg
= time
.asctime
() + "\n" + user_data
.decode
() + "进入聊天室..."
send_record
(enter_msg
)
users
[user_addr
] = user_data
.decode
('utf-8')
continue
if '--EXIT' in user_data
.decode
('utf-8'):
leave_msg
= time
.asctime
() + "\n" + users
[user_addr
] + "离开了聊天室..."
users
.pop
(user_addr
)
send_record
(leave_msg
)
elif '--USERLIST' in user_data
.decode
('utf-8'):
for user
in users
.keys
():
list_msg
= (users
[user
]+': '+user
[0]+":"+str(user
[1])).encode
()
svrsocket
.sendto
(list_msg
,user_addr
)
else:
msg
= time
.asctime
() + '\n' +user_data
.decode
('utf-8')
send_record
(msg
)
except ConnectionResetError
:
print("ConnectionResetError")
客户端
import socket
import threading
def send(sock
,addr
):
'''
该函数接受一个套接字和一个元组(地址,端口)
可通过input()获取用户输入,将信息发送给套接字
'''
while True:
string
= input()
message
= name
+ ": " + string
sock
.sendto
(message
.encode
('utf-8'),addr
)
if string
== '--EXIT':
break
def recv(sock
,addr
):
'''
该函数接受一个套接字和一个元组(地址,端口)
可通过套接字接收服务端发过来的信息
'''
sock
.sendto
(name
.encode
('utf-8'),addr
)
while True:
data
= sock
.recv
(1024)
print(data
.decode
('utf-8'))
print('____WELCOME____\n'+'EXIT -> exits\nUSERLIST -> get users')
name
= input('please input your name:')
socket
= socket
.socket
(socket
.AF_INET
,socket
.SOCK_DGRAM
)
server
= ('192.168.218.17',8080)
tr
= threading
.Thread
(target
=recv
,args
=(socket
,server
),daemon
=True)
ts
= threading
.Thread
(target
=send
,args
=(socket
,server
))
tr
.start
()
ts
.start
()
ts
.join
()
socket
.close
()
效果图
总结
可以从效果图看出来,用户输入的信息和用户们的聊天记录混在一起,确实很影响用户体验,而且在聊天的时候没有任何提示符、消息的时间刷得太多同样也很影响使用。
笔者水平有限,如有错误欢迎指正!侵权必删