1. java
  2. android
  3. c#
  4. .net
  5. javascript
  6. php
  7. jquery
  8. html
  9. sql

Java - Conexão por Sockets e Threads, transferencia de msg e arquivos por chat

Estou com um trabalho onde preciso criar um chat "empresarial", onde existe a opção de chat privado ou um em grupo com todos os membros online, a parte do chat por msg não tem muito misterio, porem estou com muita dificuldade com a parte de enviar arquivos, estou tendo muito problemas, irei colocar o código que eu tenho pronto ate o momento, e ate o momentos meus erros são na parte de receber o arquivo no servido depois enviar para o segundo usuário. Sou bem iniciante ainda!

Cliente - O cliente roda uma thread que tem como intenção pode enviar arquivos a qualquer momento, para teste eu só coloquei a condição de ter uma entrada qualquer no teclado para que ele envie o arquivo para o servido, nesse momento não ocorre nenhum erro aparente.


package client;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.Scanner;
import java.util.logging.Level;
import java.util.logging.Logger;


public class Cliente implements Runnable {

    private final String host;
    private final int porta;
    Socket cliente;

    public Cliente(String host, int porta) throws IOException {
        this.host = host;
        this.porta = porta;
        cliente = new Socket(host, porta);
    }

    @Override
    public void run() {
        try {
            Scanner s = new Scanner(System.in);
            ReceberArquivo a = new ReceberArquivo(cliente.getInputStream());
            new Thread(a).start();

            if (s.hasNext()) {
                File myFile = new File("C:/Users/Casa/1.jpg");
                FileInputStream fis = new FileInputStream(myFile);

                byte[] mybytearray = new byte[256];
                DataOutputStream os = new DataOutputStream(cliente.getOutputStream());
                System.out.println("Enviando...");
                while (true) {
                    int len = fis.read(mybytearray);
                    System.out.println(len);
                    if (len == -1) {
                        break;
                    }

                    os.write(mybytearray, 0, len);

                }
                os.flush();

            }
        } catch (IOException ex) {
            Logger.getLogger(Cliente.class.getName()).log(Level.SEVERE, null, ex);
        }

    }

}

ReceberArquivo - Classe feita com intuito de rodar uma thread que fica recebendo arquivos enviado pelo servido, os path dos arquivos foram todos colocados a mão para facilitar o teste, depois irei alterar a forma de de entrada, aqui não sei se tem problemas pq não chega a receber.


package client;

import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;


public class ReceberArquivo implements Runnable {

    public InputStream servidor;


    public ReceberArquivo(InputStream servidor) {
        this.servidor = servidor;
    }

    @Override
    public void run() {

        while (true) {
            try (InputStream is = this.servidor) {
                if (is.read() != -1) {
                    File myFile = new File("C:/Users/Casa/source-copy.jpg");
                FileOutputStream fis = new FileOutputStream(myFile);

                byte[] mybytearray = new byte[256];
                DataInputStream os = new DataInputStream(is);
                System.out.println("Recebendo...");
                while(true){
                    int len =  os.read(mybytearray);
                    if(len == -1) break;
                    fis.write(mybytearray, 0, len);

                }
                os.close();
                }
            } catch (IOException ex) {
                Logger.getLogger(ReceberArquivo.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }
}

RodarCliente - inicia a conexão

package client;



public class Client {

    public static void main(String[] args) throws Exception {
       Cliente c = new Cliente("127.0.0.1", 12345);
       new Thread(c).start();

    }
}

Servidor - No Servidor não esta chegando a fazer as operações ele para na thread que fica rodando para tratar as msg que esta logo abaixo.

package server;


import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;


public class Servidor {

    private final int porta;
    private final List<Socket> clientes;

    public Servidor(int porta) {
        this.porta = porta;
        this.clientes = new ArrayList();
    }

    public void executa() throws IOException {
        try (ServerSocket servidor = new ServerSocket(this.porta)) {
            System.out.println("Porta 12345 aberta!");

            while (true) {
                Socket cliente = servidor.accept();
                System.out.println("Nova conexão com o cliente "
                        + cliente.getInetAddress().getHostAddress());

                this.clientes.add(cliente);

                TratarArquivo tc = new TratarArquivo(cliente, this);
                new Thread(tc).start();
            }
        }
    }

    public void distribuiMensagem(Socket clienteQueEnviou, String file) throws IOException {
        System.out.println("1");
        for (Socket cliente : this.clientes) {
            System.out.println("2");
            if (!cliente.equals(clienteQueEnviou)) {
                System.out.println("3");
                File myFile = new File(file);
                FileInputStream fis = new FileInputStream(myFile);

                byte[] mybytearray = new byte[256];
                DataOutputStream os = new DataOutputStream(cliente.getOutputStream());
                System.out.println("Enviando...");
                while(true){
                    int len =  fis.read(mybytearray);
                    if(len == -1) break;
                    os.write(mybytearray, 0, len);

                }
                os.flush();
                myFile.delete();
                System.out.println("Arquivo temporario deletado");
            }
        }
    }
}

TratarArquivo - Fica preso em um loop aki pq a variavel len nunca chega em -1

package server;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;



public class TratarArquivo implements Runnable {

    private final Socket cliente;
    private final Servidor servidor;




    public TratarArquivo(Socket cliente, Servidor servidor) {
        this.cliente = cliente;
        this.servidor = servidor;
    }

    @Override
    public void run() {

        try (InputStream is = cliente.getInputStream()) {

            if (is.read() != -1) {
                System.out.println("No servidor");
                File file = new File("C:/Users/Casa/temp.jpg");
                OutputStream fos = new FileOutputStream(file);
                DataInputStream ou = new DataInputStream(is);
                byte[] mybytearray = new byte[256];
                while(true){
                    int len = ou.read(mybytearray);
                    System.out.println(len);
                     if(len==-1) break;
                    fos.write(mybytearray, 0, len);
                }
                fos.close();
                servidor.distribuiMensagem(cliente, "C:/Users/Casa/temp.jpg");
            }
        } catch (IOException ex) {
            Logger.getLogger(TratarArquivo.class.getName()).log(Level.SEVERE, null, ex);
        }

    }
}

RodarServidor - Inicia o servidor

package server;

import java.io.IOException;

public class Server {

    public static void main(String[] args) throws IOException{

        new Servidor(12345).executa();
    }
}
  • O erro atual na parte onde grava o arquivo na classe TratarArquivo e que a variavel que armazena os bytes (len) nunca fica vazia, sempre fiz 1 byte nela fazendo com o programa fique em loop infinito, ja que a condição para parada do loop e o buff estar vazio.

    Akatsuya   1 mês atrás
  • Eu atualizei minha resposta. Achon que tu não deves esperar que a variável len seja 0 e sim -1. A específicão(documentação) diz que quando os dados no DataInputStream acabem len deve ser -1, veja: https://docs.oracle.com/javase/7/docs/api/java/io/DataInputStream.html#read(byte[],%20int,%20int)

    Antônio Diego da Luz Silva   1 mês atrás
  • Para confirmar isso sugiro que ponhas a instrução: System.out.println("len: "+len); dentro do laço para veres os valores de ler.

    Antônio Diego da Luz Silva   1 mês atrás
  1. Você vai ver essas setas em qualquer página de pergunta. Com elas, você pode dizer se uma pergunta ou uma resposta foram relevantes ou não.
  2. Edite sua pergunta ou resposta caso queira alterar ou adicionar detalhes.
  3. Caso haja alguma dúvida sobre a pergunta, adicione um comentário. O espaço de respostas deve ser utilizado apenas para responder a pergunta.
  4. Se o autor da pergunta marcar uma resposta como solucionada, esta marca aparecerá.
  5. Clique aqui para mais detalhes sobre o funcionamento do GUJ!

1 resposta

Não é a resposta que estava procurando? Procure outras perguntas com as tags java threads sockets ou faça a sua própria pergunta.