请写出来
时间: 2024-02-18 08:01:16 浏览: 56
DiskImg.exe写盘工具
以下是一个简单的局域网聊天程序的Python实现,包括服务器端和客户端。该程序使用了socket、threading和queue模块,实现了多个客户端之间的聊天和在线列表功能。请注意,这只是一个简单的实现示例,具体的实现方式可能有所不同。
服务器端代码:
```python
import socket
import threading
import queue
clients = [] # 在线客户端列表
def handle_client(client_socket, client_addr, client_name, recv_queue):
"""处理客户端消息"""
try:
print(f'客户端 {client_name}({client_addr[0]}:{client_addr[1]}) 已连接')
while True:
data = client_socket.recv(1024).decode()
if data:
if data == 'list':
# 返回在线客户端列表
client_socket.sendall(f'在线客户端:{", ".join(c[1] for c in clients if c[2])}\n'.encode())
elif data.startswith('talkto '):
# 转发消息给指定客户端
_, peer_name, msg = data.split(' ', 2)
peer = next((c for c in clients if c[1] == peer_name and c[2]), None)
if peer:
peer[3].put(f'[{client_name}] {msg}')
else:
client_socket.sendall(f'客户端 {peer_name} 不在线\n'.encode())
else:
# 广播消息给所有在线客户端
for c in clients:
if c[2]:
c[3].put(f'[{client_name}] {data}')
else:
break
except Exception as e:
print(f'客户端 {client_name}({client_addr[0]}:{client_addr[1]}) 发生错误:{e}')
finally:
client_socket.close()
print(f'客户端 {client_name}({client_addr[0]}:{client_addr[1]}) 已断开')
clients.remove((client_socket, client_name, True, recv_queue))
def handle_recv(recv_queue):
"""处理消息队列"""
while True:
try:
data = recv_queue.get(timeout=1)
for c in clients:
if c[2]:
c[0].sendall(data.encode())
except queue.Empty:
pass
def main():
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(('0.0.0.0', 8888))
server_socket.listen(5)
print('服务器已启动,监听端口 8888')
threading.Thread(target=handle_recv, args=(queue.Queue(),)).start()
try:
while True:
client_socket, client_addr = server_socket.accept()
client_name, client_ip, client_port = client_socket.recv(1024).decode().split(',')
client_queue = queue.Queue()
clients.append((client_socket, client_name, True, client_queue))
threading.Thread(target=handle_client, args=(client_socket, client_addr, client_name, client_queue)).start()
except KeyboardInterrupt:
pass
finally:
for c in clients:
c[0].close()
server_socket.close()
if __name__ == '__main__':
main()
```
客户端代码:
```python
import socket
import threading
import queue
def handle_recv(client_socket):
"""接收服务器端消息"""
try:
while True:
data = client_socket.recv(1024).decode()
if data:
print(data, end='')
else:
break
except Exception as e:
print(f'接收服务器端消息发生错误:{e}')
finally:
client_socket.close()
def main():
name = input('请输入用户名:')
ip = input('请输入服务器IP地址:')
port = input('请输入服务器端口号:')
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect((ip, int(port)))
client_socket.sendall(f'{name},{socket.gethostbyname(socket.gethostname())},{client_socket.getsockname()[1]}'.encode())
threading.Thread(target=handle_recv, args=(client_socket,)).start()
while True:
cmd = input()
if cmd == 'list':
# 请求在线列表
client_socket.sendall('list'.encode())
elif cmd.startswith('talkto '):
# 发送消息给指定客户端
try:
_, peer_name, msg = cmd.split(' ', 2)
client_socket.sendall(f'talkto {peer_name} {msg}'.encode())
except ValueError:
print('命令格式错误')
else:
# 广播消息给所有在线客户端
client_socket.sendall(cmd.encode())
if __name__ == '__main__':
main()
```
在运行服务器端程序之前,需要先启动一个终端,并使用以下命令开启一个虚拟终端:
```
socat TCP-LISTEN:8888,fork EXEC:bash
```
然后在新的终端中运行服务器端程序:
```
python server.py
```
最后在客户端中运行程序:
```
python client.py
```
这样就可以在多个客户端之间进行聊天了。
阅读全文