Python套接字-在客户端上发送和接收消息

时间:2020-10-29 20:53:29

标签: python sockets

我正在使用套接字和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,但没有成功。知道我该如何解决吗?谢谢。

0 个答案:

没有答案
相关问题