Servidor de Socket:
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package server;
import java.io.*;
import java.net.*;
import java.util.*;
/**
*
* @author wolmir
*/
public class ServerChat extends Thread {
public static void main(String args[]) {
// instancia o vetor de clientes conectados
clientes = new Vector();
try {
// criando um socket que fica escutando a porta 9090.
ServerSocket s = new ServerSocket(8090);
// 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 ServerChat(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);
}
}
// 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 ServerChat(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);}
}
}
}
Cliente de socket:
package clientechat;
import java.io.*;
import java.net.*;
public class ClientedeChat extends Thread {
// Flag que indica quando se deve terminar a execução.
private static boolean done = false;
public static void main(String args[]) {
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("192.168.2.193", 8090);
// Basuma 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 ClientedeChat(conexao);
t.start();
// loop principal: obtendo uma linha digitada no teclado e
// enviando-a para o servidor.
String linha;
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);
}
}
// parte que controla a recepção de mensagens deste cliente
private Socket conexao;
// construtor que recebe o socket deste cliente
public ClientedeChat(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.
done = true;
}
}
Crie um projeto no netBeans e crie as duas classes depois rode o servidor e rode alguns clientes é um exemplo bem util…
Wolmir Garbin