Pré-requisitos: Apresentando threads na programação de socket , aplicativo de bate-papo multi-threaded | Conjunto 1

Este artigo fornece a implementação do programa cliente para o aplicativo de bate-papo multithread. Até agora, todos os exemplos de programação de soquete assumem que o cliente primeiro envia algumas informações e, em seguida, o servidor ou outros clientes respondem a essas informações.
No mundo real, pode não ser o caso. Não é necessário enviar uma mensagem a alguém para poder recebê-la. Um cliente deve receber prontamente uma mensagem sempre que for entregue a ele, ou seja, o envio e o recebimento devem ser implementados como atividades separadas, em vez de sequenciais .
Existe uma solução muito simples que usa threads para atingir essa funcionalidade. Na implementação do lado do cliente, criaremos dois threads:

  1. SendMessage: Este tópico será usado para enviar a mensagem para outros clientes. O funcionamento é muito simples, basta inserir a mensagem a ser enviada e o destinatário a ser entregue. Observe que esta implementação assume que a mensagem tem o formato mensagem # destinatário , onde destinatário é o nome do destinatário. Em seguida, ele grava a mensagem em seu fluxo de saída, que está conectado ao manipulador desse cliente. O manipulador quebra a mensagem e a parte do destinatário e entrega a um destinatário específico. Vamos ver como esse thread pode ser implementado.




    Thread sendMessage = new Thread(new Runnable() {
                @Override
                public void run() {
                    while (true) {
      
                        // read the message to deliver.
                        String msg = sc.nextLine();
                        try {
      
                            // write on the output stream
                            dos.writeUTF(msg);
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            });
  2. readMessage: uma abordagem semelhante é usada para criar um thread para receber as mensagens. Quando qualquer cliente tenta escrever neste fluxo de entrada do cliente, usamos o método readUTF() para ler essa mensagem. O seguinte trecho de como este tópico é implementado é mostrado abaixo-




    Thread readMessage = new Thread(new Runnable() {
      
                @Override
                public void run() {
      
                    while (true) {
                        try {
      
                            // read the message sent to this client
                            String msg = dis.readUTF();
                            System.out.println(msg);
                        } catch (IOException e) {
      
                            e.printStackTrace();
                        }
                    }
                }
            });

As etapas restantes da programação do lado do cliente são semelhantes aos exemplos anteriores. Uma breve explicação é a seguinte -

  1. Estabeleça uma conexão de soquete
  2. Comunicação A
    comunicação ocorre com a ajuda dos threads readMessage e sendMessage. Tópicos separados para leitura e escrita garantem o envio e recebimento simultâneo de mensagens.
// Java implementation for multithreaded chat client
// Save file as Client.java
  
import java.io.*;
import java.net.*;
import java.util.Scanner;
  
public class Client 
{
    final static int ServerPort = 1234;
  
    public static void main(String args[]) throws UnknownHostException, IOException 
    {
        Scanner scn = new Scanner(System.in);
          
        // getting localhost ip
        InetAddress ip = InetAddress.getByName("localhost");
          
        // establish the connection
        Socket s = new Socket(ip, ServerPort);
          
        // obtaining input and out streams
        DataInputStream dis = new DataInputStream(s.getInputStream());
        DataOutputStream dos = new DataOutputStream(s.getOutputStream());
  
        // sendMessage thread
        Thread sendMessage = new Thread(new Runnable() 
        {
            @Override
            public void run() {
                while (true) {
  
                    // read the message to deliver.
                    String msg = scn.nextLine();
                      
                    try {
                        // write on the output stream
                        dos.writeUTF(msg);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
          
        // readMessage thread
        Thread readMessage = new Thread(new Runnable() 
        {
            @Override
            public void run() {
  
                while (true) {
                    try {
                        // read the message sent to this client
                        String msg = dis.readUTF();
                        System.out.println(msg);
                    } catch (IOException e) {
  
                        e.printStackTrace();
                    }
                }
            }
        });
  
        sendMessage.start();
        readMessage.start();
  
    }
}

Resultado:
Do cliente 0:

hello#client 1
client 1 : heya
how are you#client 1
client 1 : fine..how about you
logout

Do cliente 1:

client 0 : hello
heya#client 0
client 0 : how are you
fine..how about you#client 0
logout

Pontos importantes :

  • Para enviar uma mensagem de qualquer cliente, digite a mensagem, seguida de um “#” e o nome do cliente destinatário. Observe que esta implementação fornece nomes como “cliente 0”, “cliente 1 ″….” Cliente n ”e, portanto, cuidadosamente os nomes devem ser anexados no final. Depois disso, pressione a tecla Enter.
  • Depois que uma mensagem é enviada, o manipulador desse cliente receberá a mensagem e ela será entregue ao cliente especificado.
  • Se algum cliente enviar uma mensagem a este cliente, o thread readMessage imprimirá automaticamente a mensagem no console.
  • Uma vez que o cliente tenha terminado de conversar, ele pode enviar uma mensagem de “logout” sem nenhum nome de destinatário para que o servidor saiba que este cliente fez logoff do sistema. Recomenda-se enviar uma mensagem de logout antes de fechar o terminal para o cliente para evitar erros.

Como executar o programa acima?

Semelhante aos exemplos anteriores, primeiro execute o servidor e, em seguida, execute várias instâncias do cliente. De cada um dos clientes, tente enviar mensagens um ao outro. Certifique-se de enviar mensagem apenas para um cliente válido, ou seja, para o cliente disponível na lista ativa.

Melhorias sugeridas

Esta foi apenas a parte explicativa de como a programação de threads e socket pode ser usada para criar programas poderosos. Existem algumas melhorias sugeridas nas implementações acima para os leitores interessados ​​-

  • Crie uma interface gráfica de usuário para clientes para enviar e receber mensagens. Uma ferramenta como o Netbeans pode ser usada para projetar uma interface rapidamente
  • Atualmente, os nomes são codificados permanentemente como cliente 0, cliente 1. Isso pode ser melhorado para usar apelidos fornecidos pelo usuário.
  • Essa implementação pode ser aprimorada para fornecer ao cliente a lista de usuários ativos no momento, para que ele possa saber quem são todos os seus amigos online. Um método simples pode ser implementado para este propósito que, quando invocado, imprime os nomes na lista ativa.

Este artigo foi contribuído por Rishabh Mahrsee . Se você gosta de GeeksforGeeks e gostaria de contribuir, você também pode escrever um artigo usando contribute.geeksforgeeks.org ou enviar o seu artigo para contribute@geeksforgeeks.org. Veja o seu artigo na página principal do GeeksforGeeks e ajude outros Geeks.

Escreva comentários se encontrar algo incorreto ou se quiser compartilhar mais informações sobre o tópico discutido acima.