使用Python实现一个简单的聊天室
Python是一个非常灵活的编程语言,我们现在到处可见用Python编写的应用程序。本文就是一个很简单的使用Python来编写的一个机遇命令行的聊天室,他非常简单和易于理解。让我们开始吧。
聊天室是什么?
聊天室就是一个媒介或者接口,允许两个或多个用户聊天或者发送信息。它既可以是一对一的聊天也可以是群聊。我们这个例子中,将会创建一个群聊天室,他可以同时支持多于两个人在线。
架构
对聊天室,我们使用服务器-客户端的架构。这就意味着一台服务器将托管多台客户机器。
准备开始:
在深入代码之前,我们需要知道的最后一件事就是,我们需要些两个script,一个是server端的,一个是client端的。我们需要很清晰地知道,client端是只和server端通信。client之间是没有通信的。下面,我们来看具体的代码。
服务器端的代码:
首先, 我们需要import两个库,一个是”socket”一个是”threading”。这两个都是内建的库,所以不需要额外进行安装。只要import他们就可以了。Socket是用来连接网络中的多个节点,并进行通信的。Threading模块提供了很简单直观的接口可以在程序中产生多个线程。下面我们来定义我们的IP和端口。这里我们只能使用没有被保留的端口,因为我们是在本地机器上测试的,假如使用了保留的端口,那么会有很多意想不到的问题。
当我们开始定义socket的时候,有两个参数(AF_INET)和(SOCK_STREAM)会被使用到。第一个表示使用internet socket另一个表示使用TCP。下面我们就来实现广播的功能。他的基本功能就是把信息发送给所有的在client列表中的客户端。这个功能还不止会用在这里,我们还会在别的地方使用他。处理客户端是非常麻烦的事情,这个也是这样。他首先会试一下能否成client端接收到信息,假如可以的话,他才会广播。
假如这里有任何的错误或者问题的话,我们这里就简单处理一下,直接把client移除了。我们已经做了很多工作,但是添加客户端到目前为止还没有实现。所以,下面我们就来实现它。在接收端,这个关键字“NICKNAME”会被发送给客户端,这也意味着我们需要他们的名称。然后,我们收到他们的nickname之后,就可以把他们加入到客户端列表了。
这个循环是一直运行得,所以多个客户端可以同时加入到服务器中来。你所需要做的就是,让他有正确的IP和端口。
代码:
#Coded by Yashraj Singh Chouhan import socket, threading #Libraries import host = '127.0.0.1' #LocalHost port = 7976 #Choosing unreserved port server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #socket initialization server.bind((host, port)) #binding host and port to socket server.listen() clients = [] nicknames = [] def broadcast(message): #broadcast function declaration for client in clients: client.send(message) def handle(client): while True: try: #recieving valid messages from client message = client.recv(1024) broadcast(message) except: #removing clients index = clients.index(client) clients.remove(client) client.close() nickname = nicknames[index] broadcast('{} left!'.format(nickname).encode('ascii')) nicknames.remove(nickname) break def receive(): #accepting multiple clients while True: client, address = server.accept() print("Connected with {}".format(str(address))) client.send('NICKNAME'.encode('ascii')) nickname = client.recv(1024).decode('ascii') nicknames.append(nickname) clients.append(client) print("Nickname is {}".format(nickname)) broadcast("{} joined!".format(nickname).encode('ascii')) client.send('Connected to server!'.encode('ascii')) thread = threading.Thread(target=handle, args=(client,)) thread.start() receive()
客户端代码:
这是第二段代码,我们为客户端实现写的代码。这个代码足够我们创建多个client而没有问题。我们还是从import socket和threading开始。在初始化socket之后,我们需要把它连接到对应的IP和端口。他们需要和服务器端的一样,这样才能工作。
现在我们可以连接服务器端了,你还记得server端会发要求来输入nickname吧,客户端接收到这个,发送nickname给服务端,他就可以进入聊天室了。假如没有接收到这个请求,那么连接就断了。现在我们连接到服务端了,还等什么?开始聊天吧。
我们写了一个write的函数来管理message的发送。假如你想知道怎么接收信息,还记得我们import的threading吗?这里我们需要两个thread来处理,就成功了。
你可能会发现我们在发送message之前,把它编码成ASCII了,这是因为我们发送的message是byte的格式,而不是string的格式。所以,记住,发送前编码,接收到后需要解码哦。
代码:
#Coded by Yashraj Singh Chouhan import socket, threading nickname = input("Choose your nickname: ") client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #socket initialization client.connect(('127.0.0.1', 7976)) #connecting client to server def receive(): while True: #making valid connection try: message = client.recv(1024).decode('ascii') if message == 'NICKNAME': client.send(nickname.encode('ascii')) else: print(message) except: #case on wrong ip/port details print("An error occured!") client.close() break def write(): while True: #message layout message = '{}: {}'.format(nickname, input('')) client.send(message.encode('ascii')) receive_thread = threading.Thread(target=receive) #receiving multiple messages receive_thread.start() write_thread = threading.Thread(target=write) #sending messages write_thread.start()
测试结果:
记住,服务器端代码要先运行,然后多个客户端可以加入。这个可以在命令行运行。但是我们需要不同的终端来分别运行他们。
这就是所有的代码了,希望你会喜欢他。
原文地址:https://hackernoon.com/creating-command-line-based-chat-room-using-python-oxu3u33
Recent Comments