基于TCP协议实现聊天室程序,分为服务器和客户端两个部分。 客户端实现以下功能: 1) 登录服务器 2) 显示、更新服务器传来的聊天室信息,进入、离开聊天室 3) 向聊天室单个成员或全体成员发送消息并接收消息。 4) 更
时间: 2024-06-09 21:09:18 浏览: 6
新个人信息,如昵称、头像等。
服务器实现以下功能: 1) 监听客户端的连接请求,接受客户端的连接。 2) 管理聊天室信息,包括聊天室成员、聊天记录等。 3) 将客户端发送的消息转发给聊天室内的其他成员。 4) 维护客户端的登录状态和个人信息。
下面是一个基于TCP协议的聊天室程序的示例代码。
服务器部分:
```python
import socket
import threading
class ChatRoomServer:
def __init__(self, host, port):
self.host = host
self.port = port
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.clients = []
self.messages = []
self.running = False
def start(self):
self.socket.bind((self.host, self.port))
self.socket.listen()
self.running = True
print(f"Server started on {self.host}:{self.port}")
while self.running:
try:
client_socket, client_address = self.socket.accept()
client_thread = threading.Thread(target=self.handle_client, args=(client_socket, client_address))
client_thread.start()
except KeyboardInterrupt:
self.running = False
self.stop()
def stop(self):
self.running = False
self.socket.close()
print("Server stopped")
def handle_client(self, client_socket, client_address):
print(f"New client connected from {client_address}")
client = ChatRoomClient(self, client_socket, client_address)
self.clients.append(client)
client.send_message("Welcome to the chat room!")
while client.connected:
try:
message = client_socket.recv(1024).decode().strip()
if message:
client.handle_message(message)
except ConnectionResetError:
client.disconnect()
self.clients.remove(client)
print(f"Client {client_address} disconnected")
def broadcast_message(self, message, sender=None):
self.messages.append(message)
for client in self.clients:
if client != sender:
client.send_message(message)
def send_private_message(self, message, recipient):
for client in self.clients:
if client.nickname == recipient:
client.send_message(message)
return
def get_chat_history(self):
return self.messages
class ChatRoomClient:
def __init__(self, server, socket, address):
self.server = server
self.socket = socket
self.address = address
self.nickname = ""
self.connected = True
def send_message(self, message):
self.socket.sendall(message.encode())
def handle_message(self, message):
if not self.nickname:
self.set_nickname(message)
elif message.startswith("/"):
self.handle_command(message)
else:
self.server.broadcast_message(f"{self.nickname}: {message}", self)
def set_nickname(self, nickname):
if nickname in [client.nickname for client in self.server.clients]:
self.send_message("Nickname already taken!")
else:
self.nickname = nickname
self.send_message(f"Welcome, {nickname}!")
self.server.broadcast_message(f"{nickname} joined the chat room!", self)
def handle_command(self, command):
if command.startswith("/pm "):
_, recipient, message = command.split(" ", 2)
self.server.send_private_message(f"{self.nickname} (private): {message}", recipient)
elif command == "/history":
chat_history = self.server.get_chat_history()
self.send_message("\n".join(chat_history))
elif command == "/quit":
self.disconnect()
else:
self.send_message("Unknown command!")
def disconnect(self):
self.connected = False
self.socket.close()
self.server.broadcast_message(f"{self.nickname} left the chat room!", self)
```
客户端部分:
```python
import socket
import threading
import sys
class ChatRoomClient:
def __init__(self, host, port):
self.host = host
self.port = port
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.connected = False
self.nickname = ""
self.chatroom = ""
self.running = False
def start(self):
self.socket.connect((self.host, self.port))
self.connected = True
self.running = True
print("Connected to server")
receive_thread = threading.Thread(target=self.receive_messages)
receive_thread.start()
while self.running:
try:
command = input("")
if not command:
continue
if not self.nickname:
self.set_nickname(command)
elif command.startswith("/"):
self.handle_command(command)
else:
self.send_message(command)
except KeyboardInterrupt:
self.running = False
self.stop()
def stop(self):
self.running = False
self.socket.close()
print("Disconnected from server")
def receive_messages(self):
while self.connected:
try:
message = self.socket.recv(1024).decode().strip()
if message:
print(message)
except ConnectionResetError:
self.disconnect()
def send_message(self, message):
self.socket.sendall(message.encode())
def set_nickname(self, nickname):
self.send_message(nickname)
response = self.socket.recv(1024).decode().strip()
if response.startswith("Welcome, "):
self.nickname = nickname
print(response)
else:
print(response)
def handle_command(self, command):
if command.startswith("/join "):
self.join_chatroom(command.split(" ")[1])
elif command.startswith("/pm "):
_, recipient, message = command.split(" ", 2)
self.send_message(f"/pm {recipient} {message}")
elif command == "/list":
self.list_chatrooms()
elif command == "/history":
self.get_chat_history()
elif command == "/quit":
self.disconnect()
else:
print("Unknown command!")
def join_chatroom(self, chatroom):
self.send_message(f"/join {chatroom}")
response = self.socket.recv(1024).decode().strip()
if response.startswith("Welcome to "):
self.chatroom = chatroom
print(response)
else:
print(response)
def list_chatrooms(self):
self.send_message("/list")
response = self.socket.recv(1024).decode().strip()
if response:
print(response)
else:
print("No chat rooms available")
def get_chat_history(self):
self.send_message("/history")
response = self.socket.recv(1024).decode().strip()
if response:
print(response)
else:
print("No chat history available")
def disconnect(self):
self.running = False
self.connected = False
self.socket.close()
if __name__ == "__main__":
host = input("Enter server IP address: ")
port = int(input("Enter server port number: "))
client = ChatRoomClient(host, port)
client.start()
```
在运行服务器代码之前,您需要在命令行中使用以下命令安装 threading 模块:
```bash
pip install threading
```
然后,在命令行中运行以下命令启动服务器:
```bash
python server.py
```
最后,在另一个命令行窗口中运行以下命令启动客户端:
```bash
python client.py
```
您可以在客户端中使用以下命令:
- `/join <chatroom>` 加入聊天室
- `/pm <recipient> <message>` 向某个成员发送私人消息
- `/list` 列出所有可用的聊天室
- `/history` 显示聊天室历史记录
- `/quit` 退出聊天室
您可以在服务器端使用 Ctrl-C 退出。
相关推荐
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![rar](https://img-home.csdnimg.cn/images/20210720083606.png)
![-](https://csdnimg.cn/download_wenku/file_type_column_c1.png)
![-](https://csdnimg.cn/download_wenku/file_type_column_c1.png)
![-](https://csdnimg.cn/download_wenku/file_type_column_c1.png)
![-](https://csdnimg.cn/download_wenku/file_type_column_c1.png)
![-](https://csdnimg.cn/download_wenku/file_type_column_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)