Olá a todos. Sou novo no fórum, porém sempre o acompanhei. Estou com um projeto de chat em java, mas acabei encontrando algumas dificuldades. Procurei em muitos fóruns (inclusive aqui) porém minha dúvida não foi sanada.
Eu já estou conseguindo fazer o recebimento e envio de string via TCP. Ao tentar enviar o arquivo, gostaria de usar o mesmo fluxo já criado. Mas tentei inúmeros exemplos que vi em fóruns, mesmo adaptando não deu certo. A minha ideia seria enviar para o servidor e dele enviar para o outro usuário que eu gostaria. Porém, já modifiquei tanto este código que não consigo mais pensar numa solução.
O segundo problema. Tenho um ArrayList de usuário que se conectam no servidor. Eu varro esta lista e envio as mensagens para quem está conectado. Contudo, eu ainda preciso melhorar o gerenciamento desses usuários. Por exemplo, ao iniciar o usuário ele abre automáticamente a caixa de envio de mensagem. Eu consigo conectar vários clientes. Mas gostaria que o usuário pudesse ter uma lista desses clientes, deleta-los, adicioná-los, pudesse enviar apenas para um caso quisesse. Enfim, controlar essa lista.
Espero que alguém possa me ajudar. Fico no aguardo.
Grande abraço e muita paz.
// SERVIDOR
import java.io.*;
import java.net.*;
import java.util.*;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.Socket;
public class ServidorMsn {
ArrayList clientesDoServidor;
ServerSocket servidorSocket;
public static void main(String[] args) {
new ServidorMsn().go(); // Quando eu iniciar o servidor, ele chamará o método go
//new ServidorMsn().TcpMsg();
//new ServidorMsn().TcpMsg();
}
public void go(){
clientesDoServidor = new ArrayList(); // Crio a ArrayList onde estará a lista de clientes que meu servidor possui
String nome;
try{
servidorSocket = new ServerSocket(5000); // Crio um socket e associo a uma porta
System.out.println("Servidor iniciado. Aguardando conexão... ");
while(true){
Socket socketCliente = servidorSocket.accept();
PrintWriter escritor = new PrintWriter(socketCliente.getOutputStream());
clientesDoServidor.add(escritor); // Add o escritor a minha lista pois é ele que irá escrever meus clientes nela
Thread t = new Thread (new AdmCliente(socketCliente)); // Crio uma Thread juntamente com um AdmCliente e associo ao socket
t.start(); // Inicio a Thread
System.out.println("Conexão estabelecida do Servidor! ");
System.out.println("IP do Cliente conectado: " +
((InetSocketAddress)socketCliente.getRemoteSocketAddress()).getAddress().getHostAddress()
+ " porta: " + ((InetSocketAddress)socketCliente.getRemoteSocketAddress()).getPort());
}
}
catch (Exception e){
System.out.println("Erro ao tentar iniciar o go() no servidor! ");
}
}
// De forma analoga ao Cliente, aqui tem-se a parte de envio de arquivo.
public void TcpMsg(){
try{
//ServerSocket servidor = new ServerSocket(5100);
while(true){
//Socket sv = servidor.accept();
//Socket socketArquivo = servidorSocket.accept();
FileInputStream file = new FileInputStream("D:\\Work\\ServidorMsn\\Arquivos Enviados");
ObjectInputStream obnoserver = new ObjectInputStream(file);
obnoserver.readObject();
System.out.println("Servidor iniciado. Aguardando conexão TcpMsg... ");
}
}
//byte[] buf = new byte[4096];
// while(true){
// int len = out.read(buf);
// if(len == -1) break;
// file.write(buf, 0, len);
// }
// }
// }
catch (Exception e){
System.out.println("Erro classe TcpMsg.");
}
}
public class AdmCliente implements Runnable{
// Declaro variaveis para o leitor e para o socket, respectivamente.
Socket socketServ;
BufferedReader leitor;
public AdmCliente (Socket socketCliente){
try {
// Abaixo, faço a associação dos sockets, crio um fluxo de leitura para o sevidor e crio um objeto leitor.
socketServ = socketCliente;
InputStreamReader leitorServ = new InputStreamReader(socketServ.getInputStream());
leitor = new BufferedReader(leitorServ);
}
catch (Exception e){
System.out.println("Erro ao tentar ler! (no servidor)");
}
}// Fecha construtora
public void run(){
String mensagem;
Object pasta;
try{
// Quando a mensagem enviada for lida, caso esta mensagem não tenha valor nulo,
//é enviado para todos a mensagem enviada (Inclusive para mim)
while((mensagem = leitor.readLine())!= null){
System.out.println("Leia:" + mensagem);
enviarParaTodos(mensagem);
System.out.println("Do cliente " +
((InetSocketAddress)socketServ.getRemoteSocketAddress()).getAddress().getHostAddress()
+ ";" + "Porta: " + ((InetSocketAddress)socketServ.getRemoteSocketAddress()).getPort());
}
while((Boolean)(pasta = leitor.readLine()!= mensagem)){
}
}
catch (Exception e){
System.out.println("Erro ao tentar enviar a mensagem do servidor! ");
}
}
} // Aqui fecha a classe Adm Cliente
public void salvarArquivoComo (File pasta){
try{
PrintWriter escritor = new PrintWriter(pasta);
escritor.println("D:\\Work\\ServidorMsn\\Arquivos Enviados");
escritor.flush();
}
catch (Exception e){
System.out.println("Erro ao tentar salvar arquivo no Servidor!");
}
}
public void enviarParaTodos(String mensagem){
Iterator i = clientesDoServidor.iterator(); // O iterator varre a minha lista de forma sequencial
while(i.hasNext())// i.hasNext retorna true se o iterator tem mais elementos a serem "varridos"
{
try{
// Caso possua mais elementos, eu crio um escritor e uso este para imprimir a mensagem para cada elemente que o iterator varrer
PrintWriter escritor = (PrintWriter)i.next();
escritor.println(mensagem);
escritor.flush(); //Flush garante o envio do ultimo pacote de dados, forçando a escrita desses dados que estão no buffer
}
catch (Exception e){
System.out.println("Erro ao tentar enviar a mensagem para todos os clientes no servidor!");
}
}
}
}
// CLIENTE
import java.awt.BorderLayout;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.*;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.ScrollPaneConstants;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Cliente2 {
JTextField saidaMsg;
JTextField nomeDaConversa;
JTextArea textoRecebido;
BufferedReader leitor;
PrintWriter escritor;
BufferedWriter bw = null;
FileWriter f;
File arquivo;
JFileChooser enviarArquivo;
Socket socket;
InputStreamReader fluxoDeLeitura;
OutputStream fluxoDearquivo;
public static void main(String[] args) {
Cliente2 cliente = new Cliente2(); // Crio um novo Cliente
cliente.janelaGrafica(); // Instancio um novo cliente chamando a interface do msn
}
private void janelaGrafica(){
JFrame janelaPrincipal = new JFrame("Janela do Fulano"); // Crio a janela
JPanel painelPrincipal = new JPanel();// Insiro um painel
// Aqui, crio uma area de texto, não editável pelo usuário e podendo ter quebra de letras e linhas
textoRecebido = new JTextArea(20, 45);
textoRecebido.setLineWrap(true);
textoRecebido.setWrapStyleWord(true);
textoRecebido.setEditable(false);
JScrollPane barraRolagem = new JScrollPane(textoRecebido); // Add barra de rolagem à minha àrea de texto
barraRolagem.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); //Seto barras de rolagens verticais e horizontais
barraRolagem.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
saidaMsg = new JTextField(40);//Crio um campo de texo com tamanho 40 de colunas
JButton botaoEnviar = new JButton("Enviar"); //Crio o botão
botaoEnviar.addActionListener(new BotaoDeEnviar()); // Add a ação ao botão, chamando a classe botaoDeEnviar e assim, seus respectivos métodos
botaoEnviar.setBounds(650, 354, 124, 57);// Estabeleço as coordenadas do botão
JButton botaoEnviarArquivo = new JButton("Enviar Arquivo"); //Crio o botão para enviar arquivo
botaoEnviarArquivo.addActionListener(new BotaoEnviarArquivo());
botaoEnviarArquivo.setBounds(250, 374, 124, 57);
JButton botaoSalvarConversa = new JButton("Salvar Conversa"); //Crio o botão para salvar conversa
botaoSalvarConversa.addActionListener(new BotaoSalvarConversa());
botaoSalvarConversa.setBounds(450, 374, 124, 57);
painelPrincipal.add(barraRolagem); // Add a barra de rolagem ao painel
painelPrincipal.add(saidaMsg); // Add o text field ao painel
painelPrincipal.add(botaoEnviar); // Add o botão no painel
painelPrincipal.add(botaoEnviarArquivo);
painelPrincipal.add(botaoSalvarConversa);
// painelPrincipal.add(botaoFecharConversa);
conexaoClienteServidor(); // Chamo o método para realizar a conexão TCP entre cliente e servidor
// Inicio aqui a thread cliente, que chama uma classe interna. Esta tem como função ler o fluxo do socket do servidor e exibir qualquer msg na textArea
Thread threadCliente = new Thread(new LeitorDeEntrada());
threadCliente.start();
janelaPrincipal.getContentPane().add(BorderLayout.CENTER, painelPrincipal); // getContentPane() retorna o painel principal da JPanel
janelaPrincipal.setBounds(100,100,600,500);
janelaPrincipal.setVisible(true);
}
public void conexaoClienteServidor(){
try
{
// Crio o Socket e add porta e Ip
socket = new Socket("127.0.0.1", 5000);
// Crio o fluxo de leitura (de entrada, obviamente) do cliente
InputStreamReader fluxoDeLeitura = new InputStreamReader(socket.getInputStream());
leitor = new BufferedReader(fluxoDeLeitura);// Aqui passo a variavel leitor do tipo buffreader e digo que ela esta no fluxo de leitura
escritor = new PrintWriter(socket.getOutputStream());
System.out.println("Conexão do cliente 2 bem sucedida! ");
}
catch(Exception e)
{
System.out.println("Erro na conexão!");
}
}
// public void conexãoTcpArquivo(){
// try{
//
// //Socket socket = new Socket("127.0.0.1",5100);
// ObjectInputStream saidaArquivo = new ObjectInputStream(socket.getInputStream());
//
// }
// catch (Exception e)
// {
// System.out.println("Erro ao tentar enviar o arquivo3 ");
// }
//
// }
//
public class BotaoDeEnviar implements ActionListener {
@Override
public void actionPerformed(ActionEvent arg0) {
try{
// Aqui pega-se o texto da saidaMsg(textField) e, através do escritor, imprime a msg no fluxo para o servidor
escritor.println(saidaMsg.getText());
escritor.flush();//Flush garante o envio do ultimo pacote de dados, forçando a escrita desses dados que estão no buffer
}
catch (Exception e)
{
System.out.println("Erro ao tentar enviar a mensagem! ");
}
saidaMsg.setText("");
saidaMsg.requestFocus();// Captura eventos do mouse, como o clique à um textField
}
}
// A partir daqui, tem- se a implementação quase pronta para enviar um arquivo.
public class BotaoEnviarArquivo implements ActionListener{
public void actionPerformed(ActionEvent arg0) {
try{
//BotaoEnviarArquivo bea = new BotaoEnviarArquivo();
//bea.conexaoTcpArquivo();
enviarArquivo = new JFileChooser();
int result = enviarArquivo.showOpenDialog(null);
if (result == JFileChooser.CANCEL_OPTION){
System.out.println("Erro ao tentar enviar o arquivo.");
}
else {
File pasta = enviarArquivo.getSelectedFile();
// FileOutputStream pastaDeSaida = new FileOutputStream(enviarArquivo.getSelectedFile());
// ObjectOutputStream obarquivo = new ObjectOutputStream(pastaDeSaida);
// fluxoDearquivo = obarquivo;
// fluxoDearquivo.printWriter(pastaDeSaida);
//
escritor = new PrintWriter(socket.getOutputStream());
escritor.println(pasta);
escritor.flush();
// byte[] buf = new byte[4096];
//
// while(true){
// int len = file.read(buf);
// if(len == -1) break;
// saidaArquivo.write(buf, 0, len);
// }
}
}
catch (Exception e)
{
System.out.println("Erro ao tentar enviar o arquivo (Excessão). ");
}
}
}
public class BotaoSalvarConversa implements ActionListener{
public void actionPerformed(ActionEvent arg0) {
try{
BotaoSalvarConversa bsc = new BotaoSalvarConversa();
bsc.janelaSalvarConversa();
}
catch (Exception e)
{
System.out.println("Erro ao tentar salvar a conversa em .txt ");
}
}
public void janelaSalvarConversa(){
//Inicio da janela de opção para salvar a conversa
JFrame janelaDeSalvar = new JFrame ("Coloque o nome do arquivo...");
JPanel painelDeSalvar = new JPanel();
nomeDaConversa = new JTextField(10);
JButton salvarNomeConversa = new JButton("Salvar Conversa!");
salvarNomeConversa.setBounds(250, 374, 124, 57);
//JButton cancelarNomeConversa = new JButton("Cancelar");
painelDeSalvar.add(nomeDaConversa);
painelDeSalvar.add(salvarNomeConversa);
//painelDeSalvar.add(cancelarNomeConversa);
janelaDeSalvar.getContentPane().add(BorderLayout.CENTER, painelDeSalvar); // getContentPane() retorna o painel principal da JPanel
janelaDeSalvar.setBounds(100,100,300,150);
janelaDeSalvar.setVisible(true);
salvarNomeConversa.addActionListener(new SalvarNomeConversa());
}
}
public class SalvarNomeConversa implements ActionListener{
public void actionPerformed(ActionEvent arg0) {
try{
nomeDaConversa.getText();
System.out.println( nomeDaConversa.getText());
arquivo = new File("D:\\Work\\ProjetoMsn\\Conversas Salvas 2\\" + nomeDaConversa.getText() + ".txt");
bw = new BufferedWriter(new FileWriter(arquivo, true));
textoRecebido.write(bw);
bw.close();
}
catch (Exception e)
{
System.out.println("Erro ao tentar salvar a conversa em .txt na classe SalvarNomeConversa");
}
}
}
public class LeitorDeEntrada implements Runnable {
public void run(){
String mensagem;
try{
// Aqui ele permanece em loop enquanto o que estiver capturando no servidor não ter valor nulo
while((mensagem = leitor.readLine())!= null) {
System.out.println("Leu:" + mensagem);
textoRecebido.append( "Fulano: " + "\n"+ mensagem + "\n");// Pega o texto que o servidor enviou (texto lido, ou recebido) e inseri no textArea
}
}
catch (Exception e)
{
System.out.println("Erro ao tentar iniciar a thread do cliente! ");
}
}
}
}