我正在使用套接字和python开发应用程序。该应用程序包含为客户端和服务器指定的文件。服务器必须从多个客户端接收连接和消息。客户消息充当命令。这些命令之一是“ SENDTO”,它允许客户向其他特定客户发送消息。
通过服务器,我可以向客户端发送消息。我无法做的是在客户端上获取该消息,同时允许该客户端发送新消息。
我的服务器代码如下:
import socket
import select
import sys
import _thread
import json
from datetime import datetime
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
if len(sys.argv) != 2:
print ("")
exit()
header = 10
listaComandos = ['SEND','SENDTO','WHO','HELP']
aux_ListaSockets = []
# endereco localhost
enderecoIP = "127.0.0.1"
#numero da porta
port = int(sys.argv[1])
#liga o servidor no localhost e na porta especificada
server.bind((enderecoIP, port))
#no maximo 20 conexoes ativas
server.listen(20)
listaDeSockets = [server]
# fim da configuracao do servidor
listaDeClientes = []
# Função para o tratamento das mensagens
def _message(client_socket):
try:
message_header = client_socket.recv(header)
if not len(message_header):
return False
message_length = int(message_header.decode('utf-8').strip())
return {'header': message_header, 'data': client_socket.recv(message_length)}
except:
return False
def clientThread(sockCliente, endereco):
#print("Cliente conectado!" + endereco[0])
data_atual = datetime.now()
data_hora = data_atual.strftime('%H:%M')
usuario = _message(sockCliente)
#Checando se o usuário já existe
usuario_decode = usuario['data'].decode('utf-8')
if usuario_decode in listaDeClientes:
str_fechamento = "recusada".encode('utf-8')
sockCliente.send(str_fechamento)
else:
str_fechamento = "aceita".encode('utf-8')
sockCliente.send(str_fechamento)
print(data_hora + '\t'+ usuario['data'].decode('utf-8') + '\t' +'Conectado')
listaDeClientes.append(usuario_decode)
aux_ListaSockets.append(sockCliente)
while True:
try:
message = sockCliente.recv(2048)
#print(message.decode('UTF-8'))
if message:
if 'SEND' in message.decode("UTF-8") and ('SENDTO' not in message.decode("UTF-8")):
msg = message.decode("UTF-8")
if " " in msg:
msg = msg.replace("SEND","")
if not msg or ('SEND' in msg):
data_atual = datetime.now()
data_hora = data_atual.strftime('%H:%M')
print(data_hora + '\t' + usuario_decode + '\t' + 'SEND\t' + 'Executado: Não')
sockCliente.send("nao_executada".encode('utf-8'))
else:
data_atual = datetime.now()
data_hora = data_atual.strftime('%H:%M')
print(data_hora + '\t' + usuario_decode + '\t' + 'SEND\t' + 'Executado: Sim')
print(usuario_decode + ' diz: ' + msg)
sockCliente.send("executada".encode('utf-8'))
elif 'SENDTO' in message.decode("UTF-8"):
msg = message.decode("UTF-8")
if " " in msg:
msg = msg.replace("SENDTO","")
if not msg or ('SENDTO' in msg):
data_atual = datetime.now()
data_hora = data_atual.strftime('%H:%M')
print(data_hora + '\t' + usuario_decode + '\t' + 'SENDTO\t' + 'Executado: Não')
sockCliente.send("nao_executada".encode('utf-8'))
else:
data_atual = datetime.now()
data_hora = data_atual.strftime('%H:%M')
print(data_hora + '\t' + usuario_decode + '\t' + 'SENDTO\t' + 'Executado: Sim')
destino = msg.split()[0]
if destino in listaDeClientes:
indexDestino = listaDeClientes.index(destino)
socketDestino = aux_ListaSockets[indexDestino]
socketDestino.send("oi".encode('utf-8'))
sockCliente.send("cliente existe".encode('utf-8'))
else:
sockCliente.send("cliente não existe".encode('utf-8'))
elif 'WHO' == message.decode("UTF-8"):
msg = message.decode("UTF-8")
if not msg:
data_atual = datetime.now()
data_hora = data_atual.strftime('%H:%M')
print(data_hora + '\t' + usuario_decode + '\t' + 'WHO\t' + 'Executado: Não')
sockCliente.send("nao_executada".encode('utf-8'))
else:
data_atual = datetime.now()
data_hora = data_atual.strftime('%H:%M')
print(data_hora + '\t' + usuario_decode + '\t' + 'WHO\t' + 'Executado: Sim')
msg = json.dumps(listaDeClientes).encode()
sockCliente.send(msg)
elif 'HELP' == message.decode("UTF-8"):
msg = message.decode("UTF-8")
if not msg:
data_atual = datetime.now()
data_hora = data_atual.strftime('%H:%M')
print(data_hora + '\t' + usuario_decode + '\t' + 'HELP\t' + 'Executado: Não')
sockCliente.send("nao_executada".encode('utf-8'))
else:
data_atual = datetime.now()
data_hora = data_atual.strftime('%H:%M')
print(data_hora + '\t' + usuario_decode + '\t' + 'HELP\t' + 'Executado: Sim')
msg = json.dumps(listaComandos).encode()
sockCliente.send(msg)
elif message:
sockCliente.send("comando não existe".encode('utf-8'))
else:
remove(sockCliente)
except:
continue
def transmissao(message, connection):
print("mensagem recebida: " + message)
# deve transmitir a mensagem de uma origem para um destino
def remove(connection):
if connection in listaDeClientes:
listaDeClientes.remove(connection)
while True:
#print(f'Ouvindo 20 em {enderecoIP}:{port}')
cliente_socket, enderecoIpDoCliente = server.accept()
#print("\nteste"+enderecoIpDoCliente[0])
listaDeSockets.append(cliente_socket)
_thread.start_new_thread(clientThread, (cliente_socket, enderecoIpDoCliente))
客户端代码如下:
import socket
import select
import sys
import json
header = 10
conexao_aceita = False
#server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
if len(sys.argv) != 4 :
print("\n")
exit()
clientName = sys.argv[1]
enderecoServidor = sys.argv[2]
portaServidor = int(sys.argv[3])
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
server_socket.connect((enderecoServidor, portaServidor))
except socket.error:
print ("Falha na conexão")
exit()
# Enviando nome do usuário ara o servidor
usuario = clientName.encode('utf-8')
usuario_header = f"{len(usuario):<{header}}".encode('utf-8')
server_socket.send(usuario_header + usuario)
while True:
if conexao_aceita == True:
# talvez colocar recebendo duas respostas
mensagem_recebida = server_socket.recv(2048)
print(mensagem_recebida.decode('utf-8'))
mensagem = input("Digite alguma mensagem: ")
server_socket.send(bytes(mensagem, encoding = 'UTF-8'))
print('Mensagem enviada')
resposta = server_socket.recv(2048)
if mensagem == 'HELP':
msg = json.loads(resposta)
print('Comandos:\n')
for m in msg:
print(m + '\n')
elif mensagem == 'WHO':
msg = json.loads(resposta)
print('Clientes:\n')
for m in msg:
print(m + '\n')
elif 'SENDTO' in mensagem:
print(resposta.decode('utf-8'))
elif mensagem:
print(resposta.decode('utf-8'))
# Validando se a conexão é válida
else:
data = server_socket.recv(1024)
if data == b'recusada':
server_socket.close()
print("Conexão recusada. O nome do usuário já existe.")
break
else:
print("Conectado com Sucesso")
conexao_aceita = True
#print(clientName +"\n"+enderecoServidor+"\n"+portaServidor)
据我了解,问题在于客户端总是等待服务器发来的消息,并在服务器不发送任何消息的时候卡住。我是使用python进行套接字编程的新手,所以我不知道自己做错了什么还是做错了。
我尝试使用select.select,但没有成功。知道我该如何解决吗?谢谢。