在这篇博客中,我们将使用 Python 实现一个功能齐全的 TCP 聊天室。我们将拥有一台服务器来托管房间,以及多个客户端连接到它并相互通信。
传输控制协议是一种面向连接的通信协议,有助于通过网络在不同设备之间交换消息。
为了实现我们的聊天室,我们将使用客户端-服务器架构。这意味着我们将拥有多个客户端(用户)和一台中央服务器来托管所有内容并为这些客户端提供数据。
1.为了设置我们的基础服务器,我们需要导入两个库,即套接字和线程。套接字库将用于建立和设置网络连接,线程库是同时执行各种任务所必需的。
import socket import threading
2. 下一个任务是定义我们的服务器数据并初始化我们的套接字。我们需要主机的 IP 地址和服务器的可用端口号。在本博客中,我们将使用地址 127.0.0.1,即我们的 localhost 和端口 5500。
端口号无关紧要,但您必须确保您使用的端口是免费且未被保留。如果您在实际服务器或虚拟机上运行此聊天室,请将聊天室服务器的 IP 地址指定为虚拟机或服务器的主机 IP 地址。
查看此保留端口号列表以获取更多信息。
# Server Data host = '127.0.0.1' port = 5500
3. 当我们定义套接字时,我们需要传递两个参数。这些定义了我们要使用的套接字类型。第一个 (AF_INET) 表明我们使用的是互联网套接字而不是 unix 套接字。第二个参数代表我们要使用的协议。 SOCK_STREAM 表示我们正在使用 TCP。
定义套接字后,我们通过传递包含这两个值的元组将其绑定或附加到我们的主机和指定端口。然后我们将服务器置于监听模式,以便它等待客户端连接并发送消息..
# Start the Server server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server.bind((host, port)) server.listen()
4.我们还将创建两个空列表,稍后我们将用它们来存储连接的客户端及其昵称。
import socket import threading
5.现在我们将定义所有有助于我们广播消息的函数。它将向每个连接的客户端发送一条消息,因此会出现在客户端列表中。
# Server Data host = '127.0.0.1' port = 5500
6.现在我们将创建一个handle()函数。该函数将负责处理来自客户端的消息。该函数将在 while 循环中运行。该函数将接受客户端作为参数并无限循环地处理它,直到发生错误或客户端本身断开连接。
# Start the Server server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server.bind((host, port)) server.listen()
7. 现在我们必须接收来自客户端的消息并将其广播给所有连接的客户端。因此,当一个客户端发送一条消息时,其他人都可以通过broadcast()函数看到该消息。现在,如果由于某种原因与该客户端的连接出现错误,我们将删除它及其昵称,关闭连接并广播该客户端已离开聊天。
# Lists For Clients and Their Nicknames clients = [] nicknames = []
当我们准备好运行我们的服务器时,我们将执行这个接收函数。一旦客户端连接到服务器,它就会向服务器发送字符串“NAME”,这将告诉客户端请求其昵称。之后,它等待响应并将具有相应昵称的客户端附加到列表中,并为该特定客户端的handle()函数启动一个线程。
8. 现在我们可以运行这个函数,我们的服务器就完成了。
# Sending Messages To All Connected Clients def broadcast(message): for client in clients: client.send(message)
现在我们要实现我们的客户端。为此,我们将再次需要导入相同的库。
# Handling Clients def handle(client): while True: try: # Broadcasting Messages message = client.recv(1024) broadcast(message) except: # Removing And Closing Clients index = clients.index(client) clients.remove(client) client.close() nickname = nicknames[index] broadcast('{} left!'.format(nickname).encode('ascii')) nicknames.remove(nickname) break
1. 客户端的第一步是选择昵称并连接到我们的服务器。我们需要知道服务器运行的确切地址和端口。作为客户端,我们连接到现有服务器,而不是绑定数据和监听。
# Receiving `Function def receive(): while True: # Accept Connection client, address = server.accept() print("Connected with {}".format(str(address))) # Request And Store Nickname client.send('NAME'.encode('ascii')) nickname = client.recv(1024).decode('ascii') nicknames.append(nickname) clients.append(client) # Print And Broadcast Nickname print("Nickname is {}".format(nickname)) broadcast("{} joined!".format(nickname).encode('ascii')) client.send('Connected to server!'.encode('ascii')) # Start Handling Thread For Client thread = threading.Thread(target=handle, args=(client,)) thread.start()
2. 现在,客户端需要有两个同时运行的线程。第一个将不断从服务器接收数据,第二个将向服务器发送我们自己的消息。
receive()
这里又出现了一个无限的 while 循环。它不断尝试接收消息并将其打印到屏幕上。但是,如果消息是“NAME”,它不会打印它,而是将其昵称发送到服务器。
书写功能相当短。它还以无限循环运行,始终等待用户的输入。一旦获得一些,它就会将其与昵称结合起来并发送给服务器。
3.我们需要做的最后一件事是启动两个运行这两个函数的线程。
import socket import threading
现在我们完成了。我们有一个功能齐全的服务器和可以连接到它并相互通信的工作客户端。
我们来测试一下吧。请记住,我们始终需要先启动服务器,否则客户端无法连接到不存在的主机。
*服务器日志:*
# Server Data host = '127.0.0.1' port = 5500
*客户端一日志:*
# Start the Server server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server.bind((host, port)) server.listen()
*客户端二日志:*
# Lists For Clients and Their Nicknames clients = [] nicknames = []
在此处查找完整代码:https://github.com/rajatuiwebdev/tcp-chatroom-in-python
在 Instagram 上关注我: https://instagram.com/rajatrajput.dev
在 LinkedIn 上关注我: https://linkedin.com/in/rajatrajput2004
以上是Python 中的 TCP 聊天室的详细内容。更多信息请关注PHP中文网其他相关文章!