elisangela.bruno
Fiz algumas alterações no seu projeto:
a) Dividi ele em 2 packages, uma é o client e o outro o server, de modo que a estrutura ficou assim:
nomeDoProjeto\src
\client
\server
\Util
b) Fiz com que as classes ficassem em arquivos separados.
c) Fiz alguns ajustes na interface, nada demais, apenas inclui alguns objetos visuais.
Portanto quando receber esta mensagem vc, por favor, faça o seguinte:
1) Crie um novo projeto java no eclipse.
2) Clrie no SRC do projeto 2 packages um chamado CLIENT e o outro SERVER.
3) Copie as classes correspondente ao client para o package CLIENT.
4) Copie as classes correspondente ao server para o package SERVER.
5) Execute o server (classe ChatServer).
6) Execute o client (classe ClientCall).
Segue abaixo as classes do CLIENT:
package client;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Label;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.io.PrintStream;
import java.net.Socket;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class ClientCall extends JFrame {
public static final int DEFAULT_PORT = 4321;
private Socket server;
private Thread reader;
public PrintStream outPut;
// Criação dos objetos da tela
private JLabel lblMiniChat = new JLabel("::.. MiniChat Conexão Socket ..::");
private JLabel lblUsuario = new JLabel("Nome do usuario");
private JButton btnLimpar = new JButton("Limpar");
private JButton btnSair = new JButton("Sair");
private JButton btnLogin = new JButton("Login");
private JButton btnSend = new JButton("Enviar");
private JTextField txtUsuario = new JTextField(15);
private JTextField inputArea = new JTextField(20);
private JTextArea outputArea = new JTextArea(10, 45);
private JComboBox cbxUsuarios = new JComboBox();
public ClientCall() {
this.initialize();
this.connect();
}
private void connect() {
try {
// Cria um socket cliente passando o endereco e a porta do servidor
this.server = new Socket("127.0.0.1", DEFAULT_PORT);
this.reader = new Reader(this);
this.outPut = new PrintStream(this.server.getOutputStream());
this.reader.setPriority(3);
this.reader.start();
} catch (IOException e) {
e.printStackTrace();
}
}
private void send(String msg) {
this.outPut.println(msg);
}
public void addLogin(String user) {
if( !user.equals(this.txtUsuario.getText())) {
if( !this.userExists(user) ) {
this.cbxUsuarios.addItem(user);
}
}
}
private boolean userExists(String user) {
boolean exist = false;
for(int i = 0; i < this.cbxUsuarios.getModel().getSize(); i++ ) {
String u = (String)this.cbxUsuarios.getModel().getElementAt(i);
if( u.equals(user)) {
exist = true;
break;
}
}
return exist;
}
public Socket getServer() {
return this.server;
}
public JTextArea getOutPutArea() {
return this.outputArea;
}
private void initialize() {
super.setTitle("::.. Comunicador Instântaneo ..::");
super.setDefaultCloseOperation(EXIT_ON_CLOSE);
super.setResizable(false);
super.setLocationRelativeTo(null);
Container janela = getContentPane();
janela.setLayout(new FlowLayout());
// Formatando Fonte
this.outputArea.setFont(new Font("Serif", Font.ITALIC, 16));
this.txtUsuario.setFont(new Font("Serif", Font.ITALIC, 16));
// Adicionado componentes
janela.add(this.lblMiniChat);
janela.add(this.lblUsuario);
janela.add(this.txtUsuario);
janela.add(this.btnLogin);
janela.add(this.outputArea);
janela.add(new Label("Digite a mensagem"));
janela.add(this.inputArea);
janela.add(this.cbxUsuarios);
janela.add(this.btnSend);
janela.add(this.btnLimpar);
janela.add(this.btnSair);
// Dimensões Janela
super.setSize(550, 350);
// Ações Botões
this.btnLimpar.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
inputArea.setText("");
}
});
this.btnLogin.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
send("LOGIN:"+txtUsuario.getText());
}
});
this.btnSend.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
StringBuilder sb = new StringBuilder(0);
sb.append("FROM:");
sb.append(txtUsuario.getText());
sb.append(";");
sb.append("TO:");
sb.append((String)cbxUsuarios.getSelectedItem());
sb.append(";");
sb.append("MSG:");
sb.append(inputArea.getText());
send(sb.toString());
}
});
this.btnSair.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
}
public static void main(String[] args) {
ClientCall tc = new ClientCall();
tc.setVisible(true);
}
}
package client;
import java.io.DataInputStream;
import java.io.IOException;
import util.Util;
//----------------------------------------------------------------------------
//A classe Reader le a entrada do soquete e atualiza a OutputArea com as
//novas mensagens.
class Reader extends Thread {
protected ClientCall client;
public Reader(ClientCall client) {
super("chatclient Reader");
this.client = client;
}
public void run() {
DataInputStream in = null;
String line;
try {
in = new DataInputStream(client.getServer().getInputStream());
while (true) {
line = in.readLine();
String login = Util.getContent("LOGIN", line);
if (login != null && login.length() != 0) {
this.client.addLogin(login);
} else {
this.client.getOutPutArea().append(line+"\n");
}
}
} catch (IOException e) {
System.out.println("Reader:" + e);
}
}
}
Segue abaixo as classes do package SERVER:
package server;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Calendar;
import java.util.Vector;
public class ChatServer extends Thread
{
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();
}
}
//----------------------------------------------------------------------------
package server;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.net.Socket;
import util.Util;
class Connection extends Thread {
static int numberOfConnections = 0;
protected Socket client;
protected DataInputStream in;
protected PrintStream out;
protected ServerWriter writer;
private String user = "";
public Connection(Socket cliente_socket, ThreadGroup CurrentConnections, int priority, ServerWriter writer) {
super(CurrentConnections, "Connection number" + numberOfConnections++);
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();
}
public String getUser() {
return this.user;
}
// 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 Comunicador Instântaneo...");
try {
while (true) {
// le uma linha de mensagem
inline = in.readLine();
// A conexao eh interrompida se null
if (inline == null) {
break;
}
String u = Util.getContent("LOGIN", inline);
if( u != null && u.length() != 0) {
this.user = u;
}
// 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) {
e.printStackTrace();
} finally {
try {
client.close();
} catch (IOException e2) {
e2.printStackTrace();
}
}
}
}
package server;
import java.io.PrintStream;
import java.util.Vector;
import util.Util;
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;
String login = Util.getContent("LOGIN", outputline);
String from = Util.getContent("FROM", outputline);
String to = Util.getContent("TO", outputline);
String msg = Util.getContent("MSG", outputline);
synchronized (server.connections) {
if (login != null) {
for (int index = 0; index < outputStreams.size(); index++) {
// Eh impressa a mensagem em cada um OutputStreams.
PrintStream out = (PrintStream) outputStreams.elementAt(index);
for (int idx = 0; idx < server.connections.size(); idx++) {
Connection c = (Connection) server.connections.elementAt(idx);
out.println("LOGIN:" + c.getUser());
}
}
} else {
for (int i = 0; i < server.connections.size(); i++) {
Connection c = (Connection) server.connections.elementAt(i);
if (c != null && c.getUser().equals(to)) {
PrintStream out = (PrintStream) outputStreams.elementAt(i);
out.println(from+" DIZ "+msg);
}
}
}
}
}
}
}
Segue abaixo a classe correspondente ao package UTIL:
package util;
public final class Util {
public static String getContent(String tag, String msg) {
String result = null;
String[] parts = msg.split(";");
for( String p : parts) {
String[] tags = p.split(":");
if(tags[0].equals(tag)) {
result = tags[1];
break;
}
}
return result;
}
}
flws