Subpage under development, new version coming soon!
Subject: Programação
blz veio, espero que dê certo. da proxima vez procuro ajudar mais, é que tou mto ocupado nestes dias :(
o viado do professor num adiou a entrega do trabalho???
ahuahsuh...
o corno fez eu imprimir 10 folhas atoa....
isso pq eu falei com ele ontem e ele disse q era pra trazer impresso hj...
ahuahsuh...
o corno fez eu imprimir 10 folhas atoa....
isso pq eu falei com ele ontem e ele disse q era pra trazer impresso hj...
massa!! hoje mais tarde vou ter um tempo pra olhar a bagaça.
tu entendeu o meu código? botou pra rodar no eclipse? se tu quiser eu te envio o workspace
tu entendeu o meu código? botou pra rodar no eclipse? se tu quiser eu te envio o workspace
isso pq eu falei com ele ontem e ele disse q era pra trazer impresso hj...
PQP ! Um professor de informática que pede pra levar código impresso !?
E eu falando de porta efêmera.... :p
PQP ! Um professor de informática que pede pra levar código impresso !?
E eu falando de porta efêmera.... :p
pra dizer a verdade nao
nao entendi pq vc criou aquela outra classe Thread e pq vc colocou o serv pra repitir oq o cliente digita
botei pra rodar sim, deu certo, o problema eh q os clientes não se interagem, tipo, no meu codigo quando eu escrevia, a frase ia para todos os frames, agora nao vai
nao entendi pq vc criou aquela outra classe Thread e pq vc colocou o serv pra repitir oq o cliente digita
botei pra rodar sim, deu certo, o problema eh q os clientes não se interagem, tipo, no meu codigo quando eu escrevia, a frase ia para todos os frames, agora nao vai
eu nao implementei a funcionalidade de broadcast ainda. coloquei para repetir somente para o servidor dizer que reebeu a msg, dá pra mudar isso na boa.
o que você colou funciona por causa do iterator, que implementa broadcast "por tabela". entretanto, não dá pra fazer quase nada das outras coisas: não dá pra controlar o frame, que vai abrir sempre... e acho que gerenciamento de nick não dá também.
eu ia colocar nick, agora... você quer que eu faça alguma coisa ou vai ficar do jeito que tá mesmo? hehehe
o que você colou funciona por causa do iterator, que implementa broadcast "por tabela". entretanto, não dá pra fazer quase nada das outras coisas: não dá pra controlar o frame, que vai abrir sempre... e acho que gerenciamento de nick não dá também.
eu ia colocar nick, agora... você quer que eu faça alguma coisa ou vai ficar do jeito que tá mesmo? hehehe
Eiro, tá pronto para um chat profissional? hehehe me diverti hoje com essa bagaça...
tentei comentar tudo mas não sei se ficou claro. qualquer dúvida pergunta.
tem:
1- mensagem de broadcast (só digitar no textbox e dar enter que vai pra todos)
2- mensagem privada (/msg nick mensagem)
3- mudança de nick (/nick novonick)
4- listar usuarios conectados (/userlist)
5- mensagem ao sair (/exit mensagem)
como falei, criei a Usuario.java, mas não usei o mecanismo das tuplas. passei logo toda a informação como referência em ThreadConexao e fiz uma lista de ThreadConexao em Servidor.java. é como extender a tua lista de sockets inicial para algo mais abrangente.
removi a contagem de usuarios conectados. esta informação é redundante: é só pegar o número de elementos na lista.
ficou OO com variáveis de estado encapsuladas. vejo um refactoring possível: no protocolo de conexao... podemos criar uma classe a parte para controlar as mensagens.
as classes seguem abaixo, como referência para os outros programadores do fórum. vou voltar pra asp.net agora...
(edited)
tentei comentar tudo mas não sei se ficou claro. qualquer dúvida pergunta.
tem:
1- mensagem de broadcast (só digitar no textbox e dar enter que vai pra todos)
2- mensagem privada (/msg nick mensagem)
3- mudança de nick (/nick novonick)
4- listar usuarios conectados (/userlist)
5- mensagem ao sair (/exit mensagem)
como falei, criei a Usuario.java, mas não usei o mecanismo das tuplas. passei logo toda a informação como referência em ThreadConexao e fiz uma lista de ThreadConexao em Servidor.java. é como extender a tua lista de sockets inicial para algo mais abrangente.
removi a contagem de usuarios conectados. esta informação é redundante: é só pegar o número de elementos na lista.
ficou OO com variáveis de estado encapsuladas. vejo um refactoring possível: no protocolo de conexao... podemos criar uma classe a parte para controlar as mensagens.
as classes seguem abaixo, como referência para os outros programadores do fórum. vou voltar pra asp.net agora...
(edited)
================ Usuario.java ===================
//classe basica, mas que sera acessada por todos os elementos do sistema... por isso, precisa ser publica
public class Usuario {
private int ID = -1;
private String nick;
public Usuario(int ID, String nick) {
this.ID = ID;
this.nick = nick;
}
public void setID(int ID) {
this.ID = ID;
}
public int getID() {
return ID;
}
public void setNick(String nick) {
this.nick = nick;
}
public String getNick() {
return this.nick;
}
}
(edited)
//classe basica, mas que sera acessada por todos os elementos do sistema... por isso, precisa ser publica
public class Usuario {
private int ID = -1;
private String nick;
public Usuario(int ID, String nick) {
this.ID = ID;
this.nick = nick;
}
public void setID(int ID) {
this.ID = ID;
}
public int getID() {
return ID;
}
public void setNick(String nick) {
this.nick = nick;
}
public String getNick() {
return this.nick;
}
}
(edited)
================ Cliente.java ===================
import java.net.*;
import java.io.*;
import javax.swing.JOptionPane;
public class Cliente {
Socket socket;
PrintWriter out = null;
BufferedReader in = null;
FrameCliente frame;
// public static final int PORTA = 1024;
private int PORTA;
public static final String SERVIDOR = "localhost";
public Cliente() {
init();
}
public void init() {
try {
this.PORTA = Integer.parseInt(JOptionPane
.showInputDialog("Informe a Porta do Servidor"));
socket = new Socket();
socket.connect(new InetSocketAddress(InetAddress
.getByName(SERVIDOR), PORTA));
out = new PrintWriter(socket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(socket
.getInputStream()));
frame = new FrameCliente(socket, out);
frame.setVisible(true);
String fromServer;
while ((fromServer = in.readLine()) != null) {
//inicia o tratamento de mensagens que vem do servidor
if (fromServer.equals("/ERRO:MAXCONN") || fromServer.startsWith("/exit")) //pára o cliente e sai do programa
break;
else if (fromServer.startsWith("/ERRO:COM")) { //usuario digitou um comando errado
frame.txfArea.append("\n*** Server: " + fromServer.substring(9));
}
else if (fromServer.startsWith("/nick ")) { //novo nick
frame.setNick(fromServer.substring(6));
}
else if (fromServer.startsWith("/userlist")) { //lista de usuarios
frame.txfArea.append("\n*** Usuários conectados: " + fromServer.substring(10));
}
else if (fromServer.startsWith("/msg ")) {
//qualquer mensagem com origem no servidor (pode ser uma mensagem de alguem - que vai inicialmente para o servidor)
frame.txfArea.append("\n" + fromServer.substring(5));
}
// TODO: Adicionar outras mensagens
}
//saindo do programa por excesso de conexoes
if (fromServer.equals("/ERRO:MAXCONN")) {
JOptionPane.showMessageDialog(null,
"Maximo numero de conexões já atingido!", "Erro",
JOptionPane.ERROR_MESSAGE);
System.out.println("Capacidade de Conexões Esgotada.");
frame.txfArea
.append("\n*** Server: Maximo numero de conexões já atingido!");
frame.dispose();
new Cliente();
}
saindo do programa por um comando /exit
else if (fromServer.startsWith("/exit")) {
System.out.println("Cliente desconectado: " + fromServer.substring(5));
frame.txfArea.append("\n*** Server: " + fromServer.substring(5));
frame.dispose();
}
fechamento "oficial" das conexoes - a lista no servidor já está atualizada, a esta altura
in.close();
socket.close();
out.close();
} catch (UnknownHostException e) {
System.err.println("Problema no host: localhost.");
System.exit(1);
} catch (IOException e) {
System.err.println("I/O exception para localhost.");
System.exit(1);
}
}
public static void main(String[] args) {
new Cliente();
}
}
(edited)
import java.net.*;
import java.io.*;
import javax.swing.JOptionPane;
public class Cliente {
Socket socket;
PrintWriter out = null;
BufferedReader in = null;
FrameCliente frame;
// public static final int PORTA = 1024;
private int PORTA;
public static final String SERVIDOR = "localhost";
public Cliente() {
init();
}
public void init() {
try {
this.PORTA = Integer.parseInt(JOptionPane
.showInputDialog("Informe a Porta do Servidor"));
socket = new Socket();
socket.connect(new InetSocketAddress(InetAddress
.getByName(SERVIDOR), PORTA));
out = new PrintWriter(socket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(socket
.getInputStream()));
frame = new FrameCliente(socket, out);
frame.setVisible(true);
String fromServer;
while ((fromServer = in.readLine()) != null) {
//inicia o tratamento de mensagens que vem do servidor
if (fromServer.equals("/ERRO:MAXCONN") || fromServer.startsWith("/exit")) //pára o cliente e sai do programa
break;
else if (fromServer.startsWith("/ERRO:COM")) { //usuario digitou um comando errado
frame.txfArea.append("\n*** Server: " + fromServer.substring(9));
}
else if (fromServer.startsWith("/nick ")) { //novo nick
frame.setNick(fromServer.substring(6));
}
else if (fromServer.startsWith("/userlist")) { //lista de usuarios
frame.txfArea.append("\n*** Usuários conectados: " + fromServer.substring(10));
}
else if (fromServer.startsWith("/msg ")) {
//qualquer mensagem com origem no servidor (pode ser uma mensagem de alguem - que vai inicialmente para o servidor)
frame.txfArea.append("\n" + fromServer.substring(5));
}
// TODO: Adicionar outras mensagens
}
//saindo do programa por excesso de conexoes
if (fromServer.equals("/ERRO:MAXCONN")) {
JOptionPane.showMessageDialog(null,
"Maximo numero de conexões já atingido!", "Erro",
JOptionPane.ERROR_MESSAGE);
System.out.println("Capacidade de Conexões Esgotada.");
frame.txfArea
.append("\n*** Server: Maximo numero de conexões já atingido!");
frame.dispose();
new Cliente();
}
saindo do programa por um comando /exit
else if (fromServer.startsWith("/exit")) {
System.out.println("Cliente desconectado: " + fromServer.substring(5));
frame.txfArea.append("\n*** Server: " + fromServer.substring(5));
frame.dispose();
}
fechamento "oficial" das conexoes - a lista no servidor já está atualizada, a esta altura
in.close();
socket.close();
out.close();
} catch (UnknownHostException e) {
System.err.println("Problema no host: localhost.");
System.exit(1);
} catch (IOException e) {
System.err.println("I/O exception para localhost.");
System.exit(1);
}
}
public static void main(String[] args) {
new Cliente();
}
}
(edited)
================ FrameCliente.java ===================
import java.awt.BorderLayout;
import javax.swing.JPanel;
import javax.swing.JFrame;
import javax.swing.JTextArea;
import java.awt.Rectangle;
import java.awt.Dimension;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JTextField;
import java.net.*;
import java.io.*;
public class FrameCliente extends JFrame {
Socket socket;
PrintWriter out;
private static final long serialVersionUID = 1L;
private JPanel jContentPane = null;
JTextArea txfArea = null;
private JTextField txfMsg = null;
String nick;
public FrameCliente(Socket socket, PrintWriter out) {
super();
this.socket = socket;
try {
this.out = out;
} catch (Exception ex) {
System.out.println(ex);
}
initialize();
}
private void initialize() {
this.setSize(600, 406);
//se o usuario fechar a janela, o programa precisa remover esta conexao - entao é como se tivesse digitado /exit
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
out.println("/exit");
System.exit(0);
}
});
this.setContentPane(getJContentPane());
this.setTitle("JFrame");
}
private JPanel getJContentPane() {
if (jContentPane == null) {
jContentPane = new JPanel();
jContentPane.setLayout(null);
jContentPane.add(getTxfArea(), null);
jContentPane.add(getTxfMsg(), null);
}
return jContentPane;
}
public JTextArea getTxfArea() {
if (txfArea == null) {
txfArea = new JTextArea();
txfArea.setBounds(new Rectangle(1, 1, 578, 338));
//mensagem de ajuda no começo do programa
txfArea.setText("Inicializando conexão... comandos (todos iniciam com /): " +
"\n /" + "nick <novo nick> - muda de nick \n /" +
"msg nick <mensagem> - envia mensagem privada para nick \n /" +
"exit <mensagem> - sai do chat exibindo mensagem como motivo \n /" +
"userlist - recupera a lista de usuarios conectados" );
}
return txfArea;
}
private JTextField getTxfMsg() {
if (txfMsg == null) {
txfMsg = new JTextField();
txfMsg.setBounds(new Rectangle(1, 348, 578, 20));
txfMsg.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent e) {
out.println(txfMsg.getText());
txfMsg.setText("");
}
});
}
return txfMsg;
}
// mudança de nick
public void setNick(String nick) {
this.nick = nick;
this.setTitle("Nickname: " + nick);
}
}
(edited)
import java.awt.BorderLayout;
import javax.swing.JPanel;
import javax.swing.JFrame;
import javax.swing.JTextArea;
import java.awt.Rectangle;
import java.awt.Dimension;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JTextField;
import java.net.*;
import java.io.*;
public class FrameCliente extends JFrame {
Socket socket;
PrintWriter out;
private static final long serialVersionUID = 1L;
private JPanel jContentPane = null;
JTextArea txfArea = null;
private JTextField txfMsg = null;
String nick;
public FrameCliente(Socket socket, PrintWriter out) {
super();
this.socket = socket;
try {
this.out = out;
} catch (Exception ex) {
System.out.println(ex);
}
initialize();
}
private void initialize() {
this.setSize(600, 406);
//se o usuario fechar a janela, o programa precisa remover esta conexao - entao é como se tivesse digitado /exit
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
out.println("/exit");
System.exit(0);
}
});
this.setContentPane(getJContentPane());
this.setTitle("JFrame");
}
private JPanel getJContentPane() {
if (jContentPane == null) {
jContentPane = new JPanel();
jContentPane.setLayout(null);
jContentPane.add(getTxfArea(), null);
jContentPane.add(getTxfMsg(), null);
}
return jContentPane;
}
public JTextArea getTxfArea() {
if (txfArea == null) {
txfArea = new JTextArea();
txfArea.setBounds(new Rectangle(1, 1, 578, 338));
//mensagem de ajuda no começo do programa
txfArea.setText("Inicializando conexão... comandos (todos iniciam com /): " +
"\n /" + "nick <novo nick> - muda de nick \n /" +
"msg nick <mensagem> - envia mensagem privada para nick \n /" +
"exit <mensagem> - sai do chat exibindo mensagem como motivo \n /" +
"userlist - recupera a lista de usuarios conectados" );
}
return txfArea;
}
private JTextField getTxfMsg() {
if (txfMsg == null) {
txfMsg = new JTextField();
txfMsg.setBounds(new Rectangle(1, 348, 578, 20));
txfMsg.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent e) {
out.println(txfMsg.getText());
txfMsg.setText("");
}
});
}
return txfMsg;
}
// mudança de nick
public void setNick(String nick) {
this.nick = nick;
this.setTitle("Nickname: " + nick);
}
}
(edited)
================ Servidor.java ===================
import java.net.*;
import java.util.*;
import java.io.*;
import javax.swing.*;
public class Servidor {
ServerSocket srvSocket;
private int PORTA, NUMCLIENTE,userID;
private List<ThreadConexao> listaThreads;
public Servidor(int port, int numcli) {
this.PORTA = port;
this.NUMCLIENTE = numcli;
this.userID = 0;
System.out.println("Iniciando servidor...");
try {
srvSocket = new ServerSocket(this.PORTA);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
listaThreads = new ArrayList<ThreadConexao>();
aguardarClientes();
}
public void aguardarClientes() {
try {
while (true) { // inicializa as threads
System.out.println("Aguardando conexões na porta " + PORTA
+ "...");
Socket s = srvSocket.accept();
if (listaThreads.size() < NUMCLIENTE) {
// numero maximo de conexoes nao atingido
userID++; //não conta usuário - só incrementa, para garantir que sempre são userID's válidos e únicos
ThreadConexao thread = new ThreadConexao(s, false,
new Usuario(userID, "Guest"
+ userID), this);
thread.start();
listaThreads.add(thread);
} else {
// numero maximo de conexoes já atingido
// esta conexao vai ser criada para ser fechada imediatamente - pesquisei e é assim com os protocolos de chat clássicos
new ThreadConexao(s, true, new Usuario(
(listaThreads.size() + 1), "Guest"
+ (listaThreads.size() + 1)), this).start();
}
System.out
.println(listaThreads.size() + " clientes conectados");
if (listaThreads.size() == NUMCLIENTE)
System.out.println("Numero máximo de conexões atingido: " + NUMCLIENTE);
}
} catch (Exception ex) {
System.out.println(ex);
System.exit(1);
}
}
public void sendBroadCast(ThreadConexao origem, String msg) {
Iterator<ThreadConexao> itOrigem;
itOrigem = listaThreads.iterator();
while (itOrigem.hasNext()) {
// envia "msg" para cada uma das threads
itOrigem.next().getPrintWriterOut().println(msg);
}
}
public void sendPrivateMsg(ThreadConexao origem, String nick, String msg) {
Iterator<ThreadConexao> itOrigem;
itOrigem = listaThreads.iterator();
while (itOrigem.hasNext()) {
// procura o usuario e envia msg para a thread
ThreadConexao t = itOrigem.next();
if (t.getUser().getNick().equals(nick)) {
t.getPrintWriterOut().println(
"/msg Msg privada de " + origem.getUser().getNick()
+ "> " + msg);
}
}
}
public void sendUserList(ThreadConexao origem) {
String userList = "";
Iterator<ThreadConexao> itOrigem;
itOrigem = listaThreads.iterator();
while (itOrigem.hasNext()) {
// vai anexando os nomes dos usuarios, separados por espaço
userList += itOrigem.next().getUser().getNick() + " ";
}
origem.getPrintWriterOut().println("/userlist " + userList);
}
//remove uma conexao da lista de conexoes apos o laço é fechado... simples assim
public void closeServerConnection(ThreadConexao thread) throws IOException {
listaThreads.remove(thread);
System.out.println(listaThreads.size() + " conectados");
}
public static void main(String[] args) {
int p, n;
p = Integer.parseInt(JOptionPane
.showInputDialog("Informe a Porta do Servidor"));
n = Integer.parseInt(JOptionPane
.showInputDialog("Informe a Quantidade Máxima de Clientes"));
new Servidor(p, n);
}
}
(edited)
import java.net.*;
import java.util.*;
import java.io.*;
import javax.swing.*;
public class Servidor {
ServerSocket srvSocket;
private int PORTA, NUMCLIENTE,userID;
private List<ThreadConexao> listaThreads;
public Servidor(int port, int numcli) {
this.PORTA = port;
this.NUMCLIENTE = numcli;
this.userID = 0;
System.out.println("Iniciando servidor...");
try {
srvSocket = new ServerSocket(this.PORTA);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
listaThreads = new ArrayList<ThreadConexao>();
aguardarClientes();
}
public void aguardarClientes() {
try {
while (true) { // inicializa as threads
System.out.println("Aguardando conexões na porta " + PORTA
+ "...");
Socket s = srvSocket.accept();
if (listaThreads.size() < NUMCLIENTE) {
// numero maximo de conexoes nao atingido
userID++; //não conta usuário - só incrementa, para garantir que sempre são userID's válidos e únicos
ThreadConexao thread = new ThreadConexao(s, false,
new Usuario(userID, "Guest"
+ userID), this);
thread.start();
listaThreads.add(thread);
} else {
// numero maximo de conexoes já atingido
// esta conexao vai ser criada para ser fechada imediatamente - pesquisei e é assim com os protocolos de chat clássicos
new ThreadConexao(s, true, new Usuario(
(listaThreads.size() + 1), "Guest"
+ (listaThreads.size() + 1)), this).start();
}
System.out
.println(listaThreads.size() + " clientes conectados");
if (listaThreads.size() == NUMCLIENTE)
System.out.println("Numero máximo de conexões atingido: " + NUMCLIENTE);
}
} catch (Exception ex) {
System.out.println(ex);
System.exit(1);
}
}
public void sendBroadCast(ThreadConexao origem, String msg) {
Iterator<ThreadConexao> itOrigem;
itOrigem = listaThreads.iterator();
while (itOrigem.hasNext()) {
// envia "msg" para cada uma das threads
itOrigem.next().getPrintWriterOut().println(msg);
}
}
public void sendPrivateMsg(ThreadConexao origem, String nick, String msg) {
Iterator<ThreadConexao> itOrigem;
itOrigem = listaThreads.iterator();
while (itOrigem.hasNext()) {
// procura o usuario e envia msg para a thread
ThreadConexao t = itOrigem.next();
if (t.getUser().getNick().equals(nick)) {
t.getPrintWriterOut().println(
"/msg Msg privada de " + origem.getUser().getNick()
+ "> " + msg);
}
}
}
public void sendUserList(ThreadConexao origem) {
String userList = "";
Iterator<ThreadConexao> itOrigem;
itOrigem = listaThreads.iterator();
while (itOrigem.hasNext()) {
// vai anexando os nomes dos usuarios, separados por espaço
userList += itOrigem.next().getUser().getNick() + " ";
}
origem.getPrintWriterOut().println("/userlist " + userList);
}
//remove uma conexao da lista de conexoes apos o laço é fechado... simples assim
public void closeServerConnection(ThreadConexao thread) throws IOException {
listaThreads.remove(thread);
System.out.println(listaThreads.size() + " conectados");
}
public static void main(String[] args) {
int p, n;
p = Integer.parseInt(JOptionPane
.showInputDialog("Informe a Porta do Servidor"));
n = Integer.parseInt(JOptionPane
.showInputDialog("Informe a Quantidade Máxima de Clientes"));
new Servidor(p, n);
}
}
(edited)
================ ThreadConexao.java ===================
import java.net.*;
import java.util.StringTokenizer;
import java.io.*;
public class ThreadConexao extends Thread {
private Socket socket = null;
private Usuario usuario;
private Servidor parent;
boolean isMax = false;
String outputLine;
PrintWriter out;
public ThreadConexao(Socket socket, boolean isMax, Usuario usuario,
Servidor parent) {
super("ThreadConexao");
System.out.println("Conexao aceita de: " + socket.getInetAddress()
+ ":" + socket.getPort());
this.socket = socket;
this.isMax = isMax;
this.usuario = usuario;
this.parent = parent;
}
public void run() {
try {
out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(socket
.getInputStream()));
String inputLine;
outputLine = null;
// este if verifica se a conexão será rejeitada
if (this.isMax) {
// conexão será rejeitada - máximo número de clientes conectados
outputLine = "/ERRO:MAXCONN";
out.println(outputLine); //envia msg para o usuario
} else { // conexão aceita - set o nick padrão para o usuário
out.println("/nick " + this.usuario.getNick());
parent.sendUserList(this); //envia a lista de usuários conectados
parent.sendBroadCast(this, "/msg *** " + this.usuario.getNick() + " entrou no chat."); //envia aviso que este usuario entrou no chat
while ((inputLine = in.readLine()) != null) {
if (inputLine.startsWith("/exit")) {
if (inputLine.length() > 5 && inputLine.charAt(5) == ' ') {
outputLine = "/exitSaiu (" + inputLine.substring(6)
+ ")"; // exibe a mensagem após /exit
parent.sendBroadCast(this, "/msg *** " + this.usuario.getNick() + " saiu (" + inputLine.substring(6) + ")"); // envia uma msg para todos
// as threads informando da
// saida deste cliente
out.println(outputLine);
break;
} else if (inputLine.length() > 5 && inputLine.charAt(5) != ' ') {
outputLine = "/ERRO:COMComando inexistente: " + inputLine;
out.println(outputLine);
continue;
} else {
outputLine = "/exit" + this.usuario.getNick() + " saiu sem motivo";
parent.sendBroadCast(this, "/msg *** " + this.usuario.getNick() + " saiu (sem motivo)"); // envia uma msg para todos as threads
// informando da saida deste cliente
out.println(outputLine);
break;
}
} else if (inputLine.startsWith("/nick ")) {
// mudança de nick
String oldNick = usuario.getNick();
this.usuario.setNick(inputLine.substring(6));
parent.sendBroadCast(this, "/msg *** " + oldNick + " mudou de nick para: " + this.usuario.getNick());
outputLine = "/nick " + this.usuario.getNick();
} else if (inputLine.startsWith("/userlist")) {
// requisição da lista de usuários conectados
if (inputLine.length() == 9) {
parent.sendUserList(this);
outputLine = "/msg Fim da lista.";
} else {
outputLine = "/ERRO:COMComando inexistente: "
+ inputLine;
}
} else if (inputLine.startsWith("/msg ")) {
// mensagem privada para outro usuário
// formato: /msg nick <texto>
StringTokenizer tok = new StringTokenizer(inputLine);
String destino = "";
String msg = "/vazio";
if (tok.nextElement().equals("/msg")) { // token /msg
if (tok.hasMoreElements()) { // token nick
destino = tok.nextToken();
if (tok.hasMoreElements()) { // primeiro token da msg
msg = tok.nextToken();
}
while (tok.hasMoreElements()) { // re-constrói a msg
msg = msg + " " + tok.nextToken();
}
if (!msg.equals("/vazio")) {
// se chegar neste ponto, pode-se enviar uma mensagem sem problema
parent.sendPrivateMsg(this, destino, msg);
outputLine = "/msg Msg privada para "
+ destino + ": " + msg;
} else { // nenhuma mensagem a ser enviada: digitou apenas: /msg nick
outputLine = "/ERRO:COMFormato inválido para /msg. Digite: /msg nick <texto da mensagem>";
}
} else { // aconteceu algum erro
outputLine = "/ERRO:COMFormato inválido para /msg. Digite: /msg nick <texto da mensagem>";
}
} else { // aconteceu algum erro
outputLine = "/ERRO:COMFormato inválido para /msg. Digite: /msg nick <texto da mensagem>";
}
} else if (inputLine.startsWith("/")) {
outputLine = "/ERRO:COMComando inexistente: "
+ inputLine;
} else { // mensagem de broadcast
outputLine = null; // não é necessário setar outputLine pois a msg vai ser passada pelo
// broadcast
parent.sendBroadCast(this, "/msg " + usuario.getNick() + "> " + inputLine);
}
out.println(outputLine);
Thread.sleep(1000);
}
}
out.close();
in.close();
socket.close();
// fecha a conexão
if (outputLine.startsWith("/exit")) {
parent.closeServerConnection(this);
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public Socket getSocket() {
return this.socket;
}
public void setSocket(Socket s) {
this.socket = s;
}
public void setUser(Usuario user) {
this.usuario = user;
}
public Usuario getUser() {
return usuario;
}
public PrintWriter getPrintWriterOut() {
return this.out;
}
public String getOutputLine() {
return this.outputLine;
}
}
(edited)
import java.net.*;
import java.util.StringTokenizer;
import java.io.*;
public class ThreadConexao extends Thread {
private Socket socket = null;
private Usuario usuario;
private Servidor parent;
boolean isMax = false;
String outputLine;
PrintWriter out;
public ThreadConexao(Socket socket, boolean isMax, Usuario usuario,
Servidor parent) {
super("ThreadConexao");
System.out.println("Conexao aceita de: " + socket.getInetAddress()
+ ":" + socket.getPort());
this.socket = socket;
this.isMax = isMax;
this.usuario = usuario;
this.parent = parent;
}
public void run() {
try {
out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(socket
.getInputStream()));
String inputLine;
outputLine = null;
// este if verifica se a conexão será rejeitada
if (this.isMax) {
// conexão será rejeitada - máximo número de clientes conectados
outputLine = "/ERRO:MAXCONN";
out.println(outputLine); //envia msg para o usuario
} else { // conexão aceita - set o nick padrão para o usuário
out.println("/nick " + this.usuario.getNick());
parent.sendUserList(this); //envia a lista de usuários conectados
parent.sendBroadCast(this, "/msg *** " + this.usuario.getNick() + " entrou no chat."); //envia aviso que este usuario entrou no chat
while ((inputLine = in.readLine()) != null) {
if (inputLine.startsWith("/exit")) {
if (inputLine.length() > 5 && inputLine.charAt(5) == ' ') {
outputLine = "/exitSaiu (" + inputLine.substring(6)
+ ")"; // exibe a mensagem após /exit
parent.sendBroadCast(this, "/msg *** " + this.usuario.getNick() + " saiu (" + inputLine.substring(6) + ")"); // envia uma msg para todos
// as threads informando da
// saida deste cliente
out.println(outputLine);
break;
} else if (inputLine.length() > 5 && inputLine.charAt(5) != ' ') {
outputLine = "/ERRO:COMComando inexistente: " + inputLine;
out.println(outputLine);
continue;
} else {
outputLine = "/exit" + this.usuario.getNick() + " saiu sem motivo";
parent.sendBroadCast(this, "/msg *** " + this.usuario.getNick() + " saiu (sem motivo)"); // envia uma msg para todos as threads
// informando da saida deste cliente
out.println(outputLine);
break;
}
} else if (inputLine.startsWith("/nick ")) {
// mudança de nick
String oldNick = usuario.getNick();
this.usuario.setNick(inputLine.substring(6));
parent.sendBroadCast(this, "/msg *** " + oldNick + " mudou de nick para: " + this.usuario.getNick());
outputLine = "/nick " + this.usuario.getNick();
} else if (inputLine.startsWith("/userlist")) {
// requisição da lista de usuários conectados
if (inputLine.length() == 9) {
parent.sendUserList(this);
outputLine = "/msg Fim da lista.";
} else {
outputLine = "/ERRO:COMComando inexistente: "
+ inputLine;
}
} else if (inputLine.startsWith("/msg ")) {
// mensagem privada para outro usuário
// formato: /msg nick <texto>
StringTokenizer tok = new StringTokenizer(inputLine);
String destino = "";
String msg = "/vazio";
if (tok.nextElement().equals("/msg")) { // token /msg
if (tok.hasMoreElements()) { // token nick
destino = tok.nextToken();
if (tok.hasMoreElements()) { // primeiro token da msg
msg = tok.nextToken();
}
while (tok.hasMoreElements()) { // re-constrói a msg
msg = msg + " " + tok.nextToken();
}
if (!msg.equals("/vazio")) {
// se chegar neste ponto, pode-se enviar uma mensagem sem problema
parent.sendPrivateMsg(this, destino, msg);
outputLine = "/msg Msg privada para "
+ destino + ": " + msg;
} else { // nenhuma mensagem a ser enviada: digitou apenas: /msg nick
outputLine = "/ERRO:COMFormato inválido para /msg. Digite: /msg nick <texto da mensagem>";
}
} else { // aconteceu algum erro
outputLine = "/ERRO:COMFormato inválido para /msg. Digite: /msg nick <texto da mensagem>";
}
} else { // aconteceu algum erro
outputLine = "/ERRO:COMFormato inválido para /msg. Digite: /msg nick <texto da mensagem>";
}
} else if (inputLine.startsWith("/")) {
outputLine = "/ERRO:COMComando inexistente: "
+ inputLine;
} else { // mensagem de broadcast
outputLine = null; // não é necessário setar outputLine pois a msg vai ser passada pelo
// broadcast
parent.sendBroadCast(this, "/msg " + usuario.getNick() + "> " + inputLine);
}
out.println(outputLine);
Thread.sleep(1000);
}
}
out.close();
in.close();
socket.close();
// fecha a conexão
if (outputLine.startsWith("/exit")) {
parent.closeServerConnection(this);
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public Socket getSocket() {
return this.socket;
}
public void setSocket(Socket s) {
this.socket = s;
}
public void setUser(Usuario user) {
this.usuario = user;
}
public Usuario getUser() {
return usuario;
}
public PrintWriter getPrintWriterOut() {
return this.out;
}
public String getOutputLine() {
return this.outputLine;
}
}
(edited)
ahuahuauha... ainda se diverti fazendo isso...
@rac2: meu fi vlw!! ta perfeito o chat!!!
agora vem a sessão de dúvidas
a primeira eh: esses substrings pq um tem (6) outro (9) outro (7)? entendi isso não
@rac2: meu fi vlw!! ta perfeito o chat!!!
agora vem a sessão de dúvidas
a primeira eh: esses substrings pq um tem (6) outro (9) outro (7)? entendi isso não