能在局域网内实现多人聊天
一、先讲一讲服务器端
其中有个get模块是自己写的
import socket
import datetime
def get_ip():
"""用来搞到IP"""
host = socket.gethostname()
ip = socket.gethostbyname(host)
return ip
def get_time():
"""得到发送时间"""
now = datetime.datetime.now()
send_time = now.strftime("%Y-%m-%d %H:%M:%S")
return send_time
需要把目录标记为源
在网上看过不少,但是大多数都不能用。。或者很粗糙,没有做什么异常处理
我写的这个经过了许多的测试,做了比较全面的异常处理,应该不会爆红字
说一下服务器端的编写思路:
主要思想:
显然对于多用户来说,我们肯定不选择用户之间直接连接,否则用户一多,就成了复杂的网状结构,显然即占用端口,又对网络资源有很高的消耗,效率低下。
所以我们编写服务器作为中转站,这样每个用户都只需要和服务器建立一个连接,然后服务器接受每个用户发来的消息,然后转发给所有其他在线用户,这样便是星型结构,十分方便且利于管理。
- 我们要利用python的特点,用一个类来封装,条理清晰,也方便以后的调用
- 有三个初始化属性:
(1)一个socket套接字
(2)一个元组,包含本机IP和指定的端口(不要急着绑定,防止持续占用端口)
(3)作为服务器端,要统计在线用户,显然我们要用字典,而不是列表 - 如何与多用户建立连接:
(1)开启服务后,绑定端口(这里不确定端口是否被占用,所以加一个捕获异常语句),绑定成功后开始监听请求,一旦收到连接请求,就正式开始accept
(2)因为服务器要连接多个用户,所以必须保持监听状态,这里用while,每建立一个连接,就开启一个线程(Thread模块上场),专门为这位用户服务,然后这个线程就一边玩去了。回头继续监听接下来的连接请求。
(3)每当有一个用户连接,便把与当前用户建立的socket放入存放用户的字典,key是用户名(客户端在连接时会要求用户输入一个用户名)然后统计当前用户数量,并打印出来。 - 接下来说一说每一个线程:
(1)每个线程将会一直循环接收当前用户发来的消息,并且在服务端显示信息。
(2)接受到消息后,用户字典中的每一个socket都会立刻把此信息发送给自己对应的用户,这就实现了服务器的转发功能。 - 最后来考虑异常处理:
(1)某个用户自行退出时,服务器端将会在recv函数这报错ConnectionResetError
所以我们要做的就是捕获以上信息,然后服务器端将会向所有用户转发,“xxx用户已退出聊天”
然后从用户字典中移除该用户的socket。
(2)当服务器被强行关闭时,用户端也会报错,我们同样捕获后,告知用户“服务器已关闭”,随后客户端将自动关闭
下面服务端代码基本是按照上述思路一步步写的(后文将会有客户端代码的讲解),正是因为我自己没找到很好的教程文章,所以掉坑无数。。于是今日写了这边文章,希望能帮到大家
imp