Erro ao receber dados via socket

8 respostas
S

Galera estou com o seguinte problema, desenvolvi uma aplicação servidor que fica escutando a porta 8081 quando novas conexões chegam, ela passa este socket para a classe grava.java que é uma thread onde cuidará desta conexão, em seguida fechara a conexao.
Então o main principal é apenas para receber as chamadas e repassa-las para a classe grava.java.
As conexões chegam a cada 1 minuto enviada por um dispositivo GPS.

Estou com 1 problema, na classe grava.java na linha 37 quando começo a fazer a leitura dos dados enviados, simplesmente ele para ali, e não continua, assim não fechando a conexão e nao podendo receber outras mais vindas do dispositivo, não dá nenhum exception, então não creio que seja erro na transferencia deve ser algo errado da minha parte.

Se eu mudar o codigo da linha 36 a 37 para o codigo da linha 39 a 41 ocorre o mesmo erro na linha 40 a aplicação para e não continua.

Se eu mudar o codigo da linha 39 a 41 para o codigo da linha 44 a 51 eu consigo pelo menos exibir o conteudo dos dados passados, mas parece que ao final da string o mesmo ocorre, simplesmente ele para mas desta forma consigo imprimir parte da mensagem.

Gostaria da opinião de vcs para me ajudar neste sistema servidor, pois não sei o que fiz errado.

Obrigado

Classe principal

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package javaservidorsocket;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

/**
 *
 * @author Shakall
 */
public class Main {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        //Declaro o ServerSocket
        ServerSocket serv = null;
        //Declaro o Socket de comunicação
        //Declaro o leitor para a entrada de dados
        try {
            //Cria o ServerSocket na porta 8080 se estiver disponível
            serv = new ServerSocket(8081);
            while (true) {
                //Aguarda uma conexão na porta especificada e cria retorna o socket que irá comunicar com o cliente
                Socket s = serv.accept();
                if (s != null) {
                   new gravar(s).start();
                }
            }

            //trata possíveis excessões de input/output. Note que as excessões são as mesmas utilizadas para as classes de java.io
        } catch (IOException e) {
            //Imprime uma notificação na saída padrão caso haja algo errado.
            System.out.println("Algum problema ocorreu para criar ou receber o socket.");
        } finally {
            try {
                //Encerro o ServerSocket
                serv.close();
            } catch (IOException e) {
            }
        }
    }
}

Classe grava

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package javaservidorsocket;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Shakall
 */
public class gravar extends Thread {

    String dados;
    Socket socket;

    public gravar(Socket socket) {
        this.socket = socket;
    }

    public void run() {
        try {
            System.out.println("Novos Dados: " + new SimpleDateFormat("dd/MM/yyyy HH:mm:ss").format(new Date()));
            InputStream in = socket.getInputStream();

            /*BufferedReader entrada = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            this.dados = entrada.readLine();*/

           /*DataInputStream data=new DataInputStream(in);
            dados=data.readUTF();
            System.out.print(dados);
            */
            
            /*byte vet[] = new byte[1];
            StringBuffer aux = new StringBuffer();
            while (in.read(vet, 0, vet.length) > 0) {
                aux.append(new String(vet));
                System.out.print(aux.charAt(aux.length() - 1));
                vet = new byte[1];
            }
            this.dados = aux.toString();*/

            System.out.println("Valor Recebido: "+this.dados);
        } catch (Exception e) {
            try {
                erro.addDados("3: " + e.getMessage());
            } catch (IOException ex) {
                Logger.getLogger(gravar.class.getName()).log(Level.SEVERE, null, ex);
            }
        } finally {
            try {
                socket.close();
                System.out.println("Fechou Socket");
            } catch (IOException ex) {
                try {
                    erro.addDados("4: " + ex.getMessage());
                    Logger.getLogger(gravar.class.getName()).log(Level.SEVERE, null, ex);
                } catch (IOException ex1) {
                    Logger.getLogger(gravar.class.getName()).log(Level.SEVERE, null, ex1);
                }
            }
        }
        //arquivo.addDados(dados);
    }
}

8 Respostas

Carlos.JavaVB

Opa cara blz
Você ja tento fazer a classe gravar implementar Runnable
public class gravar extends Thread implements Runnable
???
pode ser que a thread não inicie por isso

Diabo_Loiro

Ola não tenho tempo pra testa esse codigo mais isso aki / não é.

Opa cara blz
Você ja tento fazer a classe gravar implementar Runnable
public class gravar extends Thread implements Runnable
???
pode ser que a thread não inicie por isso

esse é um pedaço de codigo do servidor do meu projeto

pedaço de codigo do servidor no caso seria equivalente a sua classe grava ai.

class Clientes implements Runnable{
        Socket sock;
        Jogador jogad;
		Clientes(Socket s){
			sock=s;			
		}
		public void run() {
			String mensagem=null;
			while(true){
			try{
			
				  
				 InputStreamReader isReader = new InputStreamReader(sock.getInputStream());
				 BufferedReader leitor = new BufferedReader(isReader);
		    		           
				 while ((mensagem = leitor.readLine()) != null) {
					  System.out.println(mensagem);

o codigo exibe as mensagems enviadas para o servidor.

acho que voce ta errando no java I/O mesmo.

espero ter ajudado.

M

Troque a linha 32 da classe Main, troque por:

new Gravar(s).start();

Isso devido à convenção de código em Java (classes com letras maiúsculas).

Use essa classe Grava.java abaixo que deve funcionar. O método run() está comentado, mas qualquer dúvida, poste aqui.

import java.io.IOException;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Gravar extends Thread {

	String dados;
	Socket socket;

	public Gravar(Socket socket) {
		this.socket = socket;
	}

	public void run() {
		String data = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss")
				.format(new Date());
		System.out.println("Novos Dados: " + data);
		try {
			// cria um Scanner para ler da entrada
			Scanner sc = new Scanner(socket.getInputStream());
			// e um StringBuilder para armazenar os dados
			StringBuilder sb = new StringBuilder();
			// aqui, lemos cada palavra. Se preferir ler por linha, comente as
			// próximas 3 linhas de descomente as linhas logo abaixo.
			while (sc.hasNext()) {
				sb.append(sc.next()).append(' ');
			}
			// while (sc.hasNextLine()) {
			// sb.append(sc.nextLine()).append('\n');
			// }
			// armazena os dados lidos na String
			dados = sb.toString();
			// TODO ao invés de só mostrar, deve fazer algo
			System.out.println("Valor Recebido: " + dados);
		} catch (Exception e) {
			Logger.getLogger(Gravar.class.getName()).log(Level.SEVERE, null, e);
		} finally {
			try {
				socket.close();
				System.out.println("Fechou Socket");
			} catch (IOException ex) {
				Logger.getLogger(Gravar.class.getName()).log(Level.SEVERE,
						null, ex);
			}
		}
	}
}
S

Carlos.JavaVB:
Opa cara blz
Você ja tento fazer a classe gravar implementar Runnable
public class gravar extends Thread implements Runnable
???
pode ser que a thread não inicie por isso

A thread está inciiando, o problema é na hora de receber os dados passados por stream, ao final da mensagem, o programa simplesmente para, não dá um valor < 0 indicando o final da trasnferencia como é de praste, simplesmente para, ele fica aguardando mais dados.

S

Diabo Loiro:
Ola não tenho tempo pra testa esse codigo mais isso aki / não é.

Opa cara blz
Você ja tento fazer a classe gravar implementar Runnable
public class gravar extends Thread implements Runnable
???
pode ser que a thread não inicie por isso

esse é um pedaço de codigo do servidor do meu projeto

pedaço de codigo do servidor no caso seria equivalente a sua classe grava ai.

class Clientes implements Runnable{
        Socket sock;
        Jogador jogad;
		Clientes(Socket s){
			sock=s;			
		}
		public void run() {
			String mensagem=null;
			while(true){
			try{
			
				  
				 InputStreamReader isReader = new InputStreamReader(sock.getInputStream());
				 BufferedReader leitor = new BufferedReader(isReader);
		    		           
				 while ((mensagem = leitor.readLine()) != null) {
					  System.out.println(mensagem);

o codigo exibe as mensagems enviadas para o servidor.

acho que voce ta errando no java I/O mesmo.

espero ter ajudado.

Este codigo é identico a forma que eu usei na linha 36 a 37, da o mesmo problema o codigo fica parado ai, como se estivesse esperando o final da transmissao que nunca chega!

S
marcobiscaro2112:
Troque a linha 32 da classe Main, troque por:
new Gravar(s).start();
Isso devido à convenção de código em Java (classes com letras maiúsculas). Use essa classe Grava.java abaixo que deve funcionar. O método run() está comentado, mas qualquer dúvida, poste aqui.
import java.io.IOException;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Gravar extends Thread {

	String dados;
	Socket socket;

	public Gravar(Socket socket) {
		this.socket = socket;
	}

	public void run() {
		String data = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss")
				.format(new Date());
		System.out.println("Novos Dados: " + data);
		try {
			// cria um Scanner para ler da entrada
			Scanner sc = new Scanner(socket.getInputStream());
			// e um StringBuilder para armazenar os dados
			StringBuilder sb = new StringBuilder();
			// aqui, lemos cada palavra. Se preferir ler por linha, comente as
			// próximas 3 linhas de descomente as linhas logo abaixo.
			while (sc.hasNext()) {
				sb.append(sc.next()).append(' ');
			}
			// while (sc.hasNextLine()) {
			// sb.append(sc.nextLine()).append('\n');
			// }
			// armazena os dados lidos na String
			dados = sb.toString();
			// TODO ao invés de só mostrar, deve fazer algo
			System.out.println("Valor Recebido: " + dados);
		} catch (Exception e) {
			Logger.getLogger(Gravar.class.getName()).log(Level.SEVERE, null, e);
		} finally {
			try {
				socket.close();
				System.out.println("Fechou Socket");
			} catch (IOException ex) {
				Logger.getLogger(Gravar.class.getName()).log(Level.SEVERE,
						null, ex);
			}
		}
	}
}

Amigo obrigado pela ajuda, mas deu o mesmo problema na linha 29 do seu codigo ele para, sem dar nenhum exception apenas para, fica ali esperando algo.
Uma suspeita, será que esta conexão é UDP, e por isso não tem final ele fica aguardando mais envios?
Se for UDP como estou usando um metodo tcp/ip ele conseguiria pegar?
Apenas algumas ideias que passaram pela minha cabeça!

S

Deu certo da seguinte maneira.

while (true) {
                ch = (char) in.read();
                aux.append(ch);
                if (in.available() <= 0) {
                    break;
                }
            }

Obrigado a todos que tentaram me ajudar, Valeu!

M

Shakall:
Deu certo da seguinte maneira.

while (true) {
                ch = (char) in.read();
                aux.append(ch);
                if (in.available() <= 0) {
                    break;
                }
            }

Obrigado a todos que tentaram me ajudar, Valeu!


O código que eu postei espera que uma palavra esteja disponível, lê essa palavra e fica esperando por outra (ou que o fluxo seja fechado para sair do while). Ele ficava “travado” pois, provavelmente, o dispositivo cliente mandava todas as informações em uma única palavra (sem espaços) ou não fechava o fluxo corretamente. Lendo cada caractere, como você fez, soluciona o problema.

E quanto à questão de TCP ou UDP, não é o problema e nem poderia ser: como são protocolos de transporte totalmente diferentes, a conexão não conseguiria ser estabelecida corretamente.

Criado 1 de janeiro de 2010
Ultima resposta 4 de jan. de 2010
Respostas 8
Participantes 4