É o seguinte, eu tenho que desenvolver um programa de ponto eletrônico pra minha empresa, meu chefe falou pra eu estudar Sockets (que eu nem sabia o que era) ai eu comecei a estudar e decidi fazer um chat só pra fins educativos...
O problema é que o chat que eu fiz não estava mandando mensagens um para o outro, ai eu peguei alguns scripts na net pra ver como era e eles também não estão mandando mensagens...
O código é o seguinte:
- Cliente
package socketChat;
// ClienteDeChat.java
import java.io.*;
import java.net.*;
public class cliente extends Thread {
// Flag que indica quando se deve terminar a execução.
private static boolean done = false;
// parte que controla a recepção de mensagens deste cliente
private Socket conexao;
// construtor que recebe o socket deste cliente
public cliente(Socket s) {
conexao = s;
}
// execução da thread
public void run() {
try {
BufferedReader entrada = new BufferedReader(new InputStreamReader(conexao.getInputStream()));
String linha;
while (true) {
// pega o que o servidor enviou
linha = entrada.readLine();
// verifica se é uma linha válida. Pode ser que a conexão
// foi interrompida. Neste caso, a linha é null. Se isso
// ocorrer, termina-se a execução saindo com break
if (linha == null) {
System.out.println("Conexão encerrada!");
break;
}
// caso a linha não seja nula, deve-se imprimi-la
System.out.println();
System.out.println(linha);
System.out.print("...> ");
}
} catch (IOException e) {
// caso ocorra alguma exceção de E/S, mostre qual foi.
System.out.println("IOException: " + e);
}
// sinaliza para o main que a conexão encerrou.
}
public static void main(String args[]) {
String linha;
try {
// Para se conectar a algum servidor, basta se criar um objeto da classe Socket. O primeiro parâmetro é o IP ou
// o endereço da máquina a qual se quer conectar e o segundo parâmetro é a porta da aplicação. Neste caso,
// utiliza-se o IP da máquina local (127.0.0.1) e a porta da aplicação ServidorDeChat. Nada impede a mudança
// desses valores, tentando estabelecer uma conexão com outras portas em outras máquinas.
Socket conexao = new Socket("127.0.0.1", 2222);
// uma vez estabelecida a comunicação, deve-se obter os
// objetos que permitem controlar o fluxo de comunicação
PrintStream saida = new PrintStream(conexao.getOutputStream());
// enviar antes de tudo o nome do usuário
BufferedReader teclado = new BufferedReader(new InputStreamReader(System.in));
System.out.print("Entre com o seu nome: ");
String meuNome = teclado.readLine();
saida.println(meuNome);
// Uma vez que tudo está pronto, antes de iniciar o loop
// principal, executar a thread de recepção de mensagens.
Thread t = new cliente(conexao);
t.start();
// loop principal: obtendo uma linha digitada no teclado e
// enviando-a para o servidor.
while (true) {
// ler a linha digitada no teclado
System.out.print("> ");
linha = teclado.readLine();
// antes de enviar, verifica se a conexão não foi fechada
if (done) {break;}
// envia para o servidor
saida.println(linha);
}
} catch (IOException e) {
// Caso ocorra alguma excessão de E/S, mostre qual foi.
System.out.println("IOException: " + e);
}
}
}
- Servidor
package socketChat;
// ServidorDeChat.java
import java.io.*;
import java.net.*;
import java.util.*;
public class servidor extends Thread {
// Parte que controla as conexões por meio de threads.
// Note que a instanciação está no main.
private static Vector clientes;
// socket deste cliente
private Socket conexao;
// nome deste cliente
private String meuNome;
// construtor que recebe o socket deste cliente
public servidor(Socket s) {
conexao = s;
}
// execução da thread
public void run() {
try {
// objetos que permitem controlar fluxo de comunicação
BufferedReader entrada = new BufferedReader(new InputStreamReader(conexao.getInputStream()));
PrintStream saida = new PrintStream(conexao.getOutputStream());
// primeiramente, espera-se pelo nome do cliente
meuNome = entrada.readLine();
// agora, verifica se string recebida é valida, pois
// sem a conexão foi interrompida, a string é null.
// Se isso ocorrer, deve-se terminar a execução.
if (meuNome == null) {return;}
// Uma vez que se tem um cliente conectado e conhecido,
// coloca-se fluxo de saída para esse cliente no vetor de
// clientes conectados.
clientes.add(saida);
// clientes é objeto compartilhado por várias threads!
// De acordo com o manual da API, os métodos são
// sincronizados. Portanto, não há problemas de acessos
// simultâneos.
// Loop principal: esperando por alguma string do cliente.
// Quando recebe, envia a todos os conectados até que o
// cliente envie linha em branco.
// Verificar se linha é null (conexão interrompida)
// Se não for nula, pode-se compará-la com métodos string
String linha = entrada.readLine();
while (linha != null && !(linha.trim().equals(""))) {
// reenvia a linha para todos os clientes conectados
sendToAll(saida, " disse: ", linha);
// espera por uma nova linha.
linha = entrada.readLine();
}
// Uma vez que o cliente enviou linha em branco, retira-se
// fluxo de saída do vetor de clientes e fecha-se conexão.
sendToAll(saida, " saiu ", "do chat!");
clientes.remove(saida);
conexao.close();
} catch (IOException e) {
// Caso ocorra alguma excessão de E/S, mostre qual foi.
System.out.println("IOException: " + e);
}
}
// enviar uma mensagem para todos, menos para o próprio
public void sendToAll(PrintStream saida, String acao, String linha) throws IOException {
Enumeration e = clientes.elements();
while (e.hasMoreElements()) {
// obtém o fluxo de saída de um dos clientes
PrintStream chat = (PrintStream) e.nextElement();
// envia para todos, menos para o próprio usuário
if (chat != saida) {chat.println(meuNome + acao + linha);}
}
}
public static void main(String args[]) {
// instancia o vetor de clientes conectados
clientes = new Vector();
try {
// criando um socket que fica escutando a porta 2222.
ServerSocket s = new ServerSocket(2222);
// Loop principal.
while (true) {
// aguarda algum cliente se conectar. A execução do
// servidor fica bloqueada na chamada do método accept da
// classe ServerSocket. Quando algum cliente se conectar
// ao servidor, o método desbloqueia e retorna com um
// objeto da classe Socket, que é porta da comunicação.
System.out.print("Esperando alguem se conectar...");
Socket conexao = s.accept();
System.out.println("Conectou!");
// cria uma nova thread para tratar essa conexão
Thread t = new servidor(conexao);
t.start();
// voltando ao loop, esperando mais alguém se conectar.
}
} catch (IOException e) {
// caso ocorra alguma excessão de E/S, mostre qual foi.
System.out.println("IOException: " + e);
}
}
}
