写一个基于SOCKET的局域网,实现一对一通信、群聊、发送文件等功能的软件
时间: 2024-03-26 20:34:13 浏览: 18
好的,以下是一个简单的Python实现:
服务器端代码:
```python
import socket
import threading
import os
# 定义服务器IP和端口号
SERVER_IP = '127.0.0.1'
SERVER_PORT = 12345
# 定义一个字典,用于保存客户端信息
clients = {}
# 定义一个函数,用于处理客户端的消息
def handle_client(conn, addr):
while True:
try:
# 接收客户端消息
data = conn.recv(1024)
if not data:
break
# 解析客户端消息
msg = data.decode().split('|')
if msg[0] == 'login':
# 如果是登录消息,保存客户端信息
clients[msg[1]] = conn
print('%s已上线' % msg[1])
elif msg[0] == 'logout':
# 如果是退出消息,删除客户端信息
del clients[msg[1]]
print('%s已下线' % msg[1])
elif msg[0] == 'chat':
# 如果是聊天消息,转发给指定客户端
if msg[1] in clients:
clients[msg[1]].send(data)
elif msg[0] == 'broadcast':
# 如果是广播消息,转发给所有客户端
for client in clients.values():
client.send(data)
elif msg[0] == 'file':
# 如果是文件消息,接收文件并转发给指定客户端
if msg[1] in clients:
# 接收文件
filename = msg[2]
filesize = int(msg[3])
with open(filename, 'wb') as f:
recv_size = 0
while recv_size < filesize:
data = conn.recv(1024)
f.write(data)
recv_size += len(data)
# 转发文件
with open(filename, 'rb') as f:
data = f.read()
clients[msg[1]].sendall('file|%s|%d|%s' % (msg[2], len(data), data))
os.remove(filename)
except:
break
# 关闭连接
conn.close()
# 创建服务器套接字
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind((SERVER_IP, SERVER_PORT))
server_socket.listen(5)
print('服务器已启动,等待客户端连接...')
# 循环接收客户端连接请求
while True:
conn, addr = server_socket.accept()
# 创建线程处理客户端消息
threading.Thread(target=handle_client, args=(conn, addr)).start()
```
客户端代码:
```python
import socket
import threading
import os
# 定义服务器IP和端口号
SERVER_IP = '127.0.0.1'
SERVER_PORT = 12345
# 定义客户端昵称
nickname = input('请输入昵称:')
# 定义一个函数,用于接收服务器消息
def recv_message(sock):
while True:
try:
# 接收服务器消息
data = sock.recv(1024)
if not data:
break
# 解析服务器消息
msg = data.decode().split('|')
if msg[0] == 'chat':
# 如果是聊天消息,显示消息内容
print('[%s] %s' % (msg[1], msg[2]))
elif msg[0] == 'file':
# 如果是文件消息,接收文件并保存到本地
filename = msg[1]
filesize = int(msg[2])
with open(filename, 'wb') as f:
recv_size = 0
while recv_size < filesize:
data = sock.recv(1024)
f.write(data)
recv_size += len(data)
print('文件%s接收完成' % filename)
except:
break
# 关闭连接
sock.close()
print('与服务器的连接已断开')
# 创建客户端套接字并连接服务器
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect((SERVER_IP, SERVER_PORT))
# 发送登录消息到服务器
client_socket.sendall(('login|%s' % nickname).encode())
# 创建线程接收服务器消息
threading.Thread(target=recv_message, args=(client_socket,)).start()
while True:
# 输入命令
cmd = input('')
if cmd == 'exit':
# 发送退出消息到服务器
client_socket.sendall(('logout|%s' % nickname).encode())
break
elif cmd.startswith('chat'):
# 发送聊天消息到服务器
msg = cmd.split(' ', 2)
client_socket.sendall(('chat|%s|%s' % (msg[1], msg[2])).encode())
elif cmd.startswith('broadcast'):
# 发送广播消息到服务器
msg = cmd.split(' ', 1)
client_socket.sendall(('broadcast|%s' % msg[1]).encode())
elif cmd.startswith('file'):
# 发送文件消息到服务器
msg = cmd.split(' ', 2)
filename = msg[1]
filesize = os.path.getsize(filename)
with open(filename, 'rb') as f:
data = f.read()
client_socket.sendall(('file|%s|%d|%s' % (msg[2], filesize, data)).encode())
# 关闭客户端套接字
client_socket.close()
```
这个实现有很多不足之处,比如没有进行异常处理、没有对文件名和内容进行编码等,仅供参考。