Mini Chat via Socket Java
Fala galera! Estou aqui desta vez para atender a um pedido de um amigo que esta tendo dificuldades em implementar um simples chat em java.
Este, será feito utilizando Socket (NÃO SABE OQUE É SOCKET???? Então clique aqui para saber).
Agora que você já sabe, vamos mostrar os códigos do servidor e cliente com suas devidas explicações.
{
int DEFAULT_PORT=4321;
protected int port;
protected ServerSocket server_port;
protected ThreadGroup CurrentConnections;
protected Vector connections;
protected ServerWriter writer;
private Calendar datatual;
//Criar um ServerSocket public chatserver()
{
super("Server");
this.port=DEFAULT_PORT;
try
{
server_port=new ServerSocket(port);
}
catch (IOException e)
{
System.err.println(e+"Exception");
}
//Cria um threadgroup para as conexoes
CurrentConnections=new ThreadGroup("Server Connections");
//Mensagem inicial na janela do servidor System.out.println("=== ««« Conexoes Realizadas »»» ===");
//Um vetor para armazenar as conexoes
connections=new Vector();
writer=new ServerWriter(this);
//Inicia o servidor para ouvindo as conexoes this.start();
}
public void run()
{
try
{
while(true)
{
datatual = Calendar.getInstance();
Socket cliente_socket=server_port.accept();
//Exibe na janela do servidor os clientes que conectam (mostra o host
//do cliente, a porta e a data e hora da conexao
System.out.println("Host:"+cliente_socket.getInetAddress()+"³ Porta:"+
cliente_socket.getPort()+"³ "+datatual.getTime());
Connection c=new Connection(cliente_socket,CurrentConnections,3,writer);
//evita o acesso simultaneo synchronized(connections)
{
//adiciona esta nova conexao a lista connections.addElement(c);
}
}
}
catch(IOException e)
{
System.err.println(e+"Exception");
}
}
//Inicia o servidor public static void main(String[] args)
{
new chatserver();
}
}
//----------------------------------------------------------------------------
class Connection extends Thread
{
static int numberOfConnections=0;
protected Socket client;
protected DataInputStream in;
protected PrintStream out;
protected ServerWriter writer;
public Connection(Socket cliente_socket, ThreadGroup CurrentConnections,
int priority, ServerWriter writer)
{
super(CurrentConnections,"Connection number"+numberOfConnections++);
//define a prioridade this.setPriority(priority);
client=cliente_socket;
this.writer=writer;
try
{
//Atarraxa os streams aos streams de entrada e saida do socket do
//cliente e adiciona este outputstream ao vetor que contem todos
//os streams de saida, usados pelo escritor writer
in=new DataInputStream(client.getInputStream());
out=new PrintStream(client.getOutputStream());
writer.OutputStreams.addElement(out);
}
catch(IOException e)
{
try
{
client.close();
}
catch (IOException e2)
{
System.err.println("Exception while getting socket streams:"+e);
return;
}
}
//dispara Thread
this.start();
}
//O metodo run faz um laco lendo as mensagens recebidas
public void run()
{
String inline;
//Envia uma mensagem de boas vindas ao cliente out.println("Bem vindo ao MiniChat...");
try
{
while(true)
{
//le uma linha de mensagem
inline=in.readLine();
//A conexao eh interrompida se null
if (inline==null)
break;
//Joga a linha no escritor writer writer.setOutdata(inline);
synchronized(writer)
{
//chama o escritor synchronized() para evitar que duas linhas
//Connection o chamem ao mesmo tempo. Esta e uma forma de "bloqueio".
writer.notify();
}
}
}
catch(IOException e)
{}
finally
{
try
{
client.close();
}
catch(IOException e2)
{}
}
}
}
//----------------------------------------------------------------------------
class ServerWriter extends Thread
{
protected chatserver server;
public Vector OutputStreams;
public String outdata;
private String outputline;
public ServerWriter(chatserver s)
{
super(s.CurrentConnections,"Server Writer");
server=s;
OutputStreams=new Vector();
this.start();
}
public void setOutdata(String mensagem)
{
outdata=mensagem;
}
public synchronized void run()
{
while(true)
{
//A linha faz um laco para sempre, mas na vedade so e executada quando
//a condicao wait for reinicializada por um notify. Isso num bloco
//sincronizado para bloquear a linha e evitar o acesso multiplo.
try
{
this.wait();
}
catch (InterruptedException e)
{
System.out.println("Caught an Interrupted Exception");
}
outputline=outdata;
synchronized(server.connections)
{
for (int i=0 ; i<OutputStreams.size() ; i++)
{
//Eh impressa a mensagem em cada um OutputStreams. PrintStream out;
out=(PrintStream)OutputStreams.elementAt(i);
out.println(outputline);
}
}
}
}}
Agora que nosso server está no ar, vamos ao nosso cliente!
{
public static final int DEFAULT_PORT=4321;
public Socket clisoc;
private Thread reader;
public TextArea OutputArea;
public TextField InputArea, nomefield;
public PrintStream out;
public String Name;
//Cria as linhas de leitura e escrita e as inicia. public void init()
{
OutputArea=new TextArea(20,45);
InputArea=new TextField(45);
nomefield=new TextField(10);
//Tela da Applet add(new Label("MiniChat usando conexao (Socket TCP)"));
add(new Label("Nome do usuario"));
add(nomefield);
add(OutputArea);
add(new Label("Digite uma mensagem e pressione ENTER"));
add(InputArea);
resize(350,445);
try
{
//Cria um socket cliente passando o endereco e a porta do servidor clisoc=new Socket("127.0.0.1",DEFAULT_PORT);
reader=new Reader(this, OutputArea);
out=new PrintStream(clisoc.getOutputStream());
//Define prioridades desiguais para que o console seja compartilhado
//de forma efetiva.
reader.setPriority(3);
reader.start();
}
catch(IOException e)
{
System.err.println(e);
}
}
public boolean handleEvent(Event evt)
{
if (evt.target==InputArea)
{
char c=(char)evt.key;
if (c=='\n')
//Vigia se o usuario pressiona a tecla ENTER.
//Isso permite saber a mensagem esta pronta para ser enviada!
{
String InLine=InputArea.getText();
Name=nomefield.getText();
out.println(Name+">"+InLine);
InputArea.setText("");
//Envia a mensagem, mas adiciona o nome do usuario a ela para que os
//outros clientes saibam quem a enviou.
return true;
}
}
return false;
}
}
//----------------------------------------------------------------------------
//A classe Reader le a entrada do soquete e atualiza a OutputArea com as
//novas mensagens.
class Reader extends Thread
{
protected ClienteCall cliente;
private TextArea OutputArea;
public Reader(ClienteCall c, TextArea OutputArea)
{
super("chatclient Reader");
this.cliente=c;
this.OutputArea=OutputArea;
}
public void run()
{
DataInputStream in=null;
String line;
try
{
in=new DataInputStream(cliente.clisoc.getInputStream());
while(true)
{
line=in.readLine();
//Adiciona a nova mensagem a OutputArea OutputArea.appendText(line+"\r\n");
}
}
catch(IOException e)
{
System.out.println("Reader:"+e);
}
}
}
Tendo isso em mãos, agora crie uma classe applet de exemplo para execução (se quiser utilizar swingão, basta criar os forms com os actionlistener e blablabla).
ClienteCall.html
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
<head>
<title>Cliente do Chato</title>
</head>
<body>
<applet code=ClienteCall.class archive=ClienteCall.java width=710 height=540>
</applet>
</body>
</html>
Pronto! nosso chat esta implementado e funcional!!! com suporte a multi thread e tudo mais!!! Se funcionou você ficará assim ------>
Abraços de seu amigo Bruno Rafael.
Veja Também:
Introdução à Socket
Upload com Primefaces
Pdf Dentro da Aplicação Swing
Este, será feito utilizando Socket (NÃO SABE OQUE É SOCKET???? Então clique aqui para saber).
Agora que você já sabe, vamos mostrar os códigos do servidor e cliente com suas devidas explicações.
chatserver.java
import java.awt.*;
import java.net.*;
import java.io.*;
import java.util.*;
public class chatserver extends Threadimport java.net.*;
import java.io.*;
import java.util.*;
{
int DEFAULT_PORT=4321;
protected int port;
protected ServerSocket server_port;
protected ThreadGroup CurrentConnections;
protected Vector connections;
protected ServerWriter writer;
private Calendar datatual;
//Criar um ServerSocket public chatserver()
{
super("Server");
this.port=DEFAULT_PORT;
try
{
server_port=new ServerSocket(port);
}
catch (IOException e)
{
System.err.println(e+"Exception");
}
//Cria um threadgroup para as conexoes
CurrentConnections=new ThreadGroup("Server Connections");
//Mensagem inicial na janela do servidor System.out.println("=== ««« Conexoes Realizadas »»» ===");
//Um vetor para armazenar as conexoes
connections=new Vector();
writer=new ServerWriter(this);
//Inicia o servidor para ouvindo as conexoes this.start();
}
public void run()
{
try
{
while(true)
{
datatual = Calendar.getInstance();
Socket cliente_socket=server_port.accept();
//Exibe na janela do servidor os clientes que conectam (mostra o host
//do cliente, a porta e a data e hora da conexao
System.out.println("Host:"+cliente_socket.getInetAddress()+"³ Porta:"+
cliente_socket.getPort()+"³ "+datatual.getTime());
Connection c=new Connection(cliente_socket,CurrentConnections,3,writer);
//evita o acesso simultaneo synchronized(connections)
{
//adiciona esta nova conexao a lista connections.addElement(c);
}
}
}
catch(IOException e)
{
System.err.println(e+"Exception");
}
}
//Inicia o servidor public static void main(String[] args)
{
new chatserver();
}
}
//----------------------------------------------------------------------------
class Connection extends Thread
{
static int numberOfConnections=0;
protected Socket client;
protected DataInputStream in;
protected PrintStream out;
protected ServerWriter writer;
public Connection(Socket cliente_socket, ThreadGroup CurrentConnections,
int priority, ServerWriter writer)
{
super(CurrentConnections,"Connection number"+numberOfConnections++);
//define a prioridade this.setPriority(priority);
client=cliente_socket;
this.writer=writer;
try
{
//Atarraxa os streams aos streams de entrada e saida do socket do
//cliente e adiciona este outputstream ao vetor que contem todos
//os streams de saida, usados pelo escritor writer
in=new DataInputStream(client.getInputStream());
out=new PrintStream(client.getOutputStream());
writer.OutputStreams.addElement(out);
}
catch(IOException e)
{
try
{
client.close();
}
catch (IOException e2)
{
System.err.println("Exception while getting socket streams:"+e);
return;
}
}
//dispara Thread
this.start();
}
//O metodo run faz um laco lendo as mensagens recebidas
public void run()
{
String inline;
//Envia uma mensagem de boas vindas ao cliente out.println("Bem vindo ao MiniChat...");
try
{
while(true)
{
//le uma linha de mensagem
inline=in.readLine();
//A conexao eh interrompida se null
if (inline==null)
break;
//Joga a linha no escritor writer writer.setOutdata(inline);
synchronized(writer)
{
//chama o escritor synchronized() para evitar que duas linhas
//Connection o chamem ao mesmo tempo. Esta e uma forma de "bloqueio".
writer.notify();
}
}
}
catch(IOException e)
{}
finally
{
try
{
client.close();
}
catch(IOException e2)
{}
}
}
}
//----------------------------------------------------------------------------
class ServerWriter extends Thread
{
protected chatserver server;
public Vector OutputStreams;
public String outdata;
private String outputline;
public ServerWriter(chatserver s)
{
super(s.CurrentConnections,"Server Writer");
server=s;
OutputStreams=new Vector();
this.start();
}
public void setOutdata(String mensagem)
{
outdata=mensagem;
}
public synchronized void run()
{
while(true)
{
//A linha faz um laco para sempre, mas na vedade so e executada quando
//a condicao wait for reinicializada por um notify. Isso num bloco
//sincronizado para bloquear a linha e evitar o acesso multiplo.
try
{
this.wait();
}
catch (InterruptedException e)
{
System.out.println("Caught an Interrupted Exception");
}
outputline=outdata;
synchronized(server.connections)
{
for (int i=0 ; i<OutputStreams.size() ; i++)
{
//Eh impressa a mensagem em cada um OutputStreams. PrintStream out;
out=(PrintStream)OutputStreams.elementAt(i);
out.println(outputline);
}
}
}
}}
Agora que nosso server está no ar, vamos ao nosso cliente!
ClienteCall.java
import java.io.*;
import java.net.*;
import java.awt.*;
import java.applet.*;
public class ClienteCall extends Appletimport java.net.*;
import java.awt.*;
import java.applet.*;
{
public static final int DEFAULT_PORT=4321;
public Socket clisoc;
private Thread reader;
public TextArea OutputArea;
public TextField InputArea, nomefield;
public PrintStream out;
public String Name;
//Cria as linhas de leitura e escrita e as inicia. public void init()
{
OutputArea=new TextArea(20,45);
InputArea=new TextField(45);
nomefield=new TextField(10);
//Tela da Applet add(new Label("MiniChat usando conexao (Socket TCP)"));
add(new Label("Nome do usuario"));
add(nomefield);
add(OutputArea);
add(new Label("Digite uma mensagem e pressione ENTER"));
add(InputArea);
resize(350,445);
try
{
//Cria um socket cliente passando o endereco e a porta do servidor clisoc=new Socket("127.0.0.1",DEFAULT_PORT);
reader=new Reader(this, OutputArea);
out=new PrintStream(clisoc.getOutputStream());
//Define prioridades desiguais para que o console seja compartilhado
//de forma efetiva.
reader.setPriority(3);
reader.start();
}
catch(IOException e)
{
System.err.println(e);
}
}
public boolean handleEvent(Event evt)
{
if (evt.target==InputArea)
{
char c=(char)evt.key;
if (c=='\n')
//Vigia se o usuario pressiona a tecla ENTER.
//Isso permite saber a mensagem esta pronta para ser enviada!
{
String InLine=InputArea.getText();
Name=nomefield.getText();
out.println(Name+">"+InLine);
InputArea.setText("");
//Envia a mensagem, mas adiciona o nome do usuario a ela para que os
//outros clientes saibam quem a enviou.
return true;
}
}
return false;
}
}
//----------------------------------------------------------------------------
//A classe Reader le a entrada do soquete e atualiza a OutputArea com as
//novas mensagens.
class Reader extends Thread
{
protected ClienteCall cliente;
private TextArea OutputArea;
public Reader(ClienteCall c, TextArea OutputArea)
{
super("chatclient Reader");
this.cliente=c;
this.OutputArea=OutputArea;
}
public void run()
{
DataInputStream in=null;
String line;
try
{
in=new DataInputStream(cliente.clisoc.getInputStream());
while(true)
{
line=in.readLine();
//Adiciona a nova mensagem a OutputArea OutputArea.appendText(line+"\r\n");
}
}
catch(IOException e)
{
System.out.println("Reader:"+e);
}
}
}
Tendo isso em mãos, agora crie uma classe applet de exemplo para execução (se quiser utilizar swingão, basta criar os forms com os actionlistener e blablabla).
ClienteCall.html
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
<head>
<title>Cliente do Chato</title>
</head>
<body>
<applet code=ClienteCall.class archive=ClienteCall.java width=710 height=540>
</applet>
</body>
</html>
Pronto! nosso chat esta implementado e funcional!!! com suporte a multi thread e tudo mais!!! Se funcionou você ficará assim ------>
Abraços de seu amigo Bruno Rafael.
Veja Também:
Introdução à Socket
Upload com Primefaces
Pdf Dentro da Aplicação Swing
Gostou? Curta nossa página:
https://www.facebook.com/Javanamente?bookmark_t=page
Parceiros:
Rota Urbana:https://www.facebook.com/RotaUrbana
Execute TI: http://www.executeti.com.br/
TaLegal: http://mastalegal.com.br/
https://www.facebook.com/Javanamente?bookmark_t=page
Parceiros:
Rota Urbana:https://www.facebook.com/RotaUrbana
Execute TI: http://www.executeti.com.br/
TaLegal: http://mastalegal.com.br/
Comentários
Postar um comentário