Python3聊天简单实现的自我学习笔记
准备工作
对于聊天服务器来说,需要有一个或者多个客户端。可以自己编写也可以使用MUD客户端。本次使用了MUD客户端,因为下载很慢,所以上传一下我下载好的。链接:https://pan.baidu.com/s/1TR9vWJaqem4Pn-37C5ZLQA
提取码:6rl5 。操作很简单输入对应的ip地址和端口号然后连接就行。
简单的服务器代码 (Server)
from asyncore import dispatcher
from asynchat import async_chat
import socket, asyncore
PORT = 7777
class ChatSession(async_chat):
def __init__(self, sock):
async_chat.__init__(self, sock)
self.set_terminator(('\r\n').encode())
self.data = []
def collect_incoming_data(self, data):
self.data.append(data.decode())
def found_terminator(self):
line = ''.join(self.data)
self.data = []
print(line)
class ChatServer(dispatcher):
def __init__(self, port):
dispatcher.__init__(self)
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
self.set_reuse_addr()
self.bind(('', port))
self.listen(5)
self.sessions = []
def handle_accept(self):
conn, addr = self.accept()
self.sessions.append(ChatSession(conn))
if __name__ == '__main__':
s = ChatServer(PORT)
try: asyncore.loop()
except KeyboardInterrupt: print()
ChatServer类
init()方法
当我们运行服务器程序事,if name == ‘main’:下的代码块将被执行。调用了ChatServer()方法进行初始化服务器,方法中调用方法create_socket()来创建一个套接字,接着调用方法bind()方法将套接字绑定到特定的端口并使用listen()方法让套接字监听到来的连接。bind()方法中指定主机名和端口号,主机名为一个空的字符串,代表着localhost,端口号为7777。listen()方法中的5代表着最大连接数。还有两行代买set_reuse_addr()和self.sessions=[]。前者方法可以使得重用原来的端口号。后者将session内容设置为空(初始化)。
handle_accept()方法
accept()用来接收客户端的连接请求,返回一个新的套接字(与socket()返回的套接字不同,多个客户端多次调用该方法产生的套接字都不同)。self.sessions.append(ChatSession(conn))这行代码的作用是创建一个新的ChatSession对象,并且将器添加到session的末尾。
ChatSession类
init()方法
self.set_terminator((’\r\n’).encode())作用是将行结束符设置成为“\r\n”。这里需要将两个结束符转换为字符串,否则出现错误:
argument should be integer or bytes-like object, not 'str'
这里需要将字符串转换为字节,通过encode()方法。字节转换成字符串的方法是decode();
self.data = []初始化数据,将之后读取到的数据存在字符串列表data中。
collect_incoming_data()和found_terminator()方法
在模块asynchat中有一个async_chat类,它的优点是隐藏了大部分的基本读写操作。让async_chat发挥作用,只需要重写两个方法collect_incoming_data()和found_terminator()。每当从套接字conn中读取一些文本后,都会调用collect_incoming_data();然而读取到结束符的时候将会调用found_terminator()。这里的结束符就是“\r\n”,在初始化的时候通过调用set_terminator()将结束符告诉了async_chat对象。
collect_incoming_data()方法中self.data.append(data.decode())将读取到的数据转换后储存在字符串列表data中,当读取到结束符(设置好的换行符)就调用found_terminator()方法,在该方法中我们将读取到的数据进行整合(join)处理。处理完一行后再讲data清空(初始化)。然后在服务器端输出结果。
如有错误,求指正。本人也在学习中~