Socket- does not receive the message completely

3

I have these codes: I'm still testing ...

Client system:

private void btComunicarActionPerformed(java.awt.event.ActionEvent evt) {                                            
        List<PessoaMOD> pessoas = new ArrayList<PessoaMOD>();

        for (int i = 1; i <= 400; i++) {
            pessoas.add(new PessoaMOD(i,
                    "Pessoa " + i,
                    "111.111.111.11",
                    "11.111.111-1",
                    "Rua Violetas " + i,
                    "Numero " + i,
                    "Complemento " + i,
                    "Bairro " + i,
                    "Cidade " + i,
                    "Estado" + i,
                    "Telefone 1" + i,
                    "Telefone 2" + i,
                    "Email" + i,
                    'f'));
        }

        try {
            Socket cliente = new Socket("127.0.0.1", 12345);
            enviarMensagem(serializarPessoa(pessoas), cliente);
            cliente.close();
        } catch (Exception e) {
            System.out.println("Erro: " + e.getMessage());
        } finally {
        }
    }                                           

    public byte[] serializarPessoa(List<PessoaMOD> pessoas) throws IOException {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        DataOutputStream dos = new DataOutputStream(bos);
        dos.writeInt(pessoas.size()); // tamanho da lista
        int cont = 0;
        for (PessoaMOD p : pessoas) {
            dos.writeInt(p.getId()); // id da pessoa
            dos.writeUTF(p.getNome());
            dos.writeUTF(p.getCpf());
            dos.writeUTF(p.getRg());
            dos.writeUTF(p.getEndereco());
            dos.writeUTF(p.getNumero());
            dos.writeUTF(p.getComplemento());
            dos.writeUTF(p.getBairro());
            dos.writeUTF(p.getCidade());
            dos.writeUTF(p.getEstado());
            dos.writeUTF(p.getTelefone1());
            dos.writeUTF(p.getTelefone2());
            dos.writeUTF(p.getEmail());
            dos.writeChar(p.getPerfil());//Nome da pessoa
        }
        return bos.toByteArray();
    }

    public void enviarMensagem(byte[] mensagem, Socket socket) throws IOException {
        DataOutputStream out = new DataOutputStream(socket.getOutputStream());
        System.out.println("Lenght: " + mensagem.length);
        out.writeInt(mensagem.length); //O tamanho da mensagem
        out.write(mensagem); //Os dados
        out.flush();
        out.close();
    }

Server system:

private void btIniciarActionPerformed(java.awt.event.ActionEvent evt) {                                          
        new Thread() {
            @Override
            public void run() {
                try {
                    ServerSocket servidor = new ServerSocket(12345);
                    System.out.println("Servidor ouvindo a porta 12345");
                    while (true) {
                        Socket cliente = servidor.accept();
                        DataInputStream entrada = new DataInputStream(cliente.getInputStream());

                        int tamanhoMsg = entrada.readInt();
                        System.out.println("Tam. Msg.: " + tamanhoMsg);

                        byte[] bytes = new byte[tamanhoMsg];
                        entrada.read(bytes, 0 , bytes.length);
                        System.out.println("Bytes size: " + bytes.length);

                        DataInputStream entrada2 = new DataInputStream(new ByteArrayInputStream(bytes));

                        int tamanhoLista = entrada2.readInt();

                        int id;
                        String nome;
                        String cpf;
                        String rg;
                        String endereco;
                        String numero;
                        String complemento;
                        String bairro;
                        String cidade;
                        String estado;
                        String telefone1;
                        String telefone2;
                        String email;
                        char perfil;

                        for (int i = 0; i < tamanhoLista; i++) {
                            id = entrada2.readInt();
                            nome = entrada2.readUTF();
                            cpf = entrada2.readUTF();
                            rg = entrada2.readUTF();
                            endereco = entrada2.readUTF();
                            numero = entrada2.readUTF();
                            complemento = entrada2.readUTF();
                            bairro = entrada2.readUTF();
                            cidade = entrada2.readUTF();
                            estado = entrada2.readUTF();
                            telefone1 = entrada2.readUTF();
                            telefone2 = entrada2.readUTF();
                            email = entrada2.readUTF();
                            perfil = entrada2.readChar();

                            System.out.println("Id: " + id);
                            System.out.println("Nome: " + nome);
                            System.out.println("Cpf: " + cpf);
                            System.out.println("Rg: " + rg);
                            System.out.println("Endereço: " + endereco);
                            System.out.println("Número: " + numero);
                            System.out.println("Complemento: " + complemento);
                            System.out.println("Bairro: " + bairro);
                            System.out.println("Cidade: " + cidade);
                            System.out.println("Estado: " + estado);
                            System.out.println("Telefone 1: " + telefone1);
                            System.out.println("Telefone 2: " + telefone2);
                            System.out.println("Email: " + email);
                            System.out.println("Perfil: " + perfil);
                            System.out.println("");
                        }
                        entrada.close();
                        entrada2.close();
                        cliente.close();
                    }
                } catch (Exception e) {
                    System.out.println("Erro: " + e.getMessage());
                } finally {
                }
            }
        }.start();
    }    

It happens that the message does not come complete, I have to execute it and the list comes up to person 37, sometimes to person 392, every hour comes a lot of people from the list ...

The message size variable and that of list size are coming right ...

    
asked by anonymous 25.02.2016 / 19:57

2 answers

3

You are calling input.read () only once. In this case it will not wait until it has enough bytes to fill the buffer; will return as soon as it has anything received, even if it is 1 byte. If it returns 0 bytes then the connection has been broken. While the connection exists the read () expects. Typically it will deliver, at every return, what fits in a TCP packet, whose size ranges from 60 to about 1400 bytes.

The solution is to loop and call read () multiple times until you have read the expected number of bytes (and treat the case of receiving 0 bytes)

    
26.02.2016 / 05:21
3

As @epx already mentioned, data is transmitted over the network in blocks, so it takes a loop to recompose the data blocks until the expected total bytes are received.

One advantage of using serialization with ObjectOutputStream and ObjectInputStream is that these classes already have the control needed to send and read the correct amount of bytes.

To solve the problem in your case, without the use of other classes, you can use the readFully() method that already contains the loop. Example:

entrada.readFully(bytes);

To get an idea of what it does, the implementation of the method that actually executes is like this:

public final void readFully(byte b[], int off, int len) throws IOException {
    if (len < 0)
        throw new IndexOutOfBoundsException();
    int n = 0;
    while (n < len) {
        int count = in.read(b, off + n, len - n);
        if (count < 0)
            throw new EOFException();
        n += count;
    }
}
    
26.02.2016 / 06:56