Re:Enviar mensagem Client/Servidor (Sockets) só funciona se eu fechar o outputstream?

7 respostas
T

Pergunto se é obrigatório que você use “Buffered” alguma coisa no seu programa. Se for, você precisa fazer o seguinte:

  • Para cada linha que você manda, dê um “flush” (obviamente isso “nega” o benefício de usar um BufferedWriter, mas…) Você precisa então abrir o socket com a opção TCP_NODELAY (veja o método setTcpNoDelay(true) de java.net.Socket.)

  • Para ler, não há muitos problemas com BufferedReader se você abriu o socket no lado client conforme indicado.

7 Respostas

T

Para que serve um servidor que só recebe, não manda nada? Implemente a parte que manda alguma coisa. (Eu já reparei que sockets não funcionam direito se um lado só manda e outro só recebe. )

T

Outra coisa é que se um lado lê as coisas com “readLine” (ou seja, requer que a mensagem seja terminada por CR+LF, no caso do Windows, ou LF no caso do Linux/Unix), então o outro lado deve mandar as coisas usando “write” e “newLine”. Você não está esquecendo de mandar um “newLine”?

noelrocha

Galera, não sei se o que estou perguntando é obvio, porem nao consigo entender:

Fiz um brincadera entre sockets, um cliente que fica enviando mensagens que você digita e um servidor que imprime essas mensagens.

Estou Usando BufferedWriter no cliente p/ enviar as msg e BufferedReader no servidor p/ receber as msg. Porem, se envio uma mensagem p/ o servidor da seguinte forma:

output = new BufferedWriter(new OutputStreamWriter(
                           this.clientSocket.getOutputStream()));
 output.write("Teste") ;
 output.flush();

A msg não chega no servidor, ela só chega se eu fizer:

output = new BufferedWriter(new OutputStreamWriter(
                           this.clientSocket.getOutputStream()));
 output.write("Teste") ;
 output.flush(); //o flush passa a ser desnecessario pois o close faz um flush
 output.close();

Isso me parace não estar certo pois se fecho o stream de saida, não consigo mais “escrever” no serivor, somente se eu me reconectar.

Estou usando java 1.6beta em um Debian.

Segue abaixo o código completo do teste que estou fazendo, na ordem Servidor, TrataCliente (Thread que trata cada conexao no servidor) e Cliente:

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

public class Servidor {
	private ServerSocket serverSocket ;

	public void iniciaServidor() {
		try {

			serverSocket = new ServerSocket(12345);

			System.out.printf("Servidor escutando porta: %d \n", 12345);

			while (true) {
				new TrataCliente(serverSocket.accept()).start() ;
			}
			
		} catch (IOException e) {
			System.out.println("## ERRO: Ao escutar porata 12345");
			e.printStackTrace();
		}
		
	}
	

	public static void main(String args[]) {
		Servidor servidor = new Servidor() ;
		servidor.iniciaServidor() ;
	}
	

}
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;

public class TrataCliente extends Thread {

	private Socket clientSocket;

	private BufferedReader input;

	public TrataCliente(Socket clientSocket) {
		this.clientSocket = clientSocket;

		try {

			input = new BufferedReader(new InputStreamReader(this.clientSocket
					.getInputStream()));
			
		} catch (IOException e) {
			System.out.println("## ERRO: Ao acessar streams de entrada e saida do cliente ##");
			e.printStackTrace();
		}

	}
	
	@Override
	public void run() {
		String mensagem = null ;
		while(true && !clientSocket.isClosed()) {	
			try {
				mensagem = input.readLine() ;
			} catch (IOException e) {
				System.out.println("## ERRO: Ao ler mensagem do cliente ##");
				e.printStackTrace();
			}
			
			if (mensagem != null) {
				System.out.println("=> Mensagem Recebida");
				System.out.println(mensagem);
			}
		}

	}
	

}
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;

public class Cliente {

	private Socket clientSocket;

	private BufferedWriter output;

	public void conecta(String endereco, int porta) {
		try {
			System.out.printf("Conectando ao servidor %s na porta %d \n",
					endereco, porta);
			clientSocket = new Socket(endereco, porta);
		} catch (UnknownHostException e) {
			System.out.println("## ERRO: Servidor nao encontrado ##");
			e.printStackTrace();
		} catch (IOException e) {
			System.out.println("## ERRO: Ao conectar no servidor ##");
			e.printStackTrace();
		}

		try {
			output = new BufferedWriter(new OutputStreamWriter(
					this.clientSocket.getOutputStream()));
		} catch (IOException e) {
			System.out
					.println("## ERRO: Ao acessar streams de entrada e saida do cliente ##");
			e.printStackTrace();
		}
	}

	public void desconecta() {
		try {
			output.close();
			clientSocket.close();
		} catch (IOException e) {
			System.out.println("## ERRO: Ao desconectar do servidor ##");
			e.printStackTrace();
		}
	}

	public void enviaMensagem(String mensagem) {
		try {
			System.out.println("=> Enviando mensagem: " + mensagem);
			output.write(mensagem) ;
			output.flush();
		} catch (IOException e) {
			System.out.println("## ERRO: Ao enviar mensagem");
			e.printStackTrace();
		}

	}

	public static void main(String... args) {
		Scanner scanner = new Scanner(System.in) ;
		Cliente cliente = new Cliente();
		cliente.conecta("localhost", 12345);
		String mensagem = null ;
		System.out.println("Digite uma mensagem e tecle enter, para sair digite bye");
		while (!(mensagem = scanner.nextLine()).equalsIgnoreCase("bye") ) {
			cliente.enviaMensagem(mensagem);
		}
		cliente.desconecta() ;
		
	}

}
noelrocha

Não é obrigatorio o uso de “Buffered”, porem eu achei que seria o mais correto…

Mas mesmo que eu faça:

clientSocket.getOutputStream().write("teste".getBytes()) ;
clientSocket.getOutputStream().flush() ;

Não funciona! :frowning:

noelrocha

Mesmo usando o tcpnodelay, não funciona!

noelrocha

era exatamente oq fatava!

Funcionou, valeu Thingol!

noelrocha

Agora estou com problemas no envio de arquivos

byte[] tempBuf = new byte[256];
            while (in.read(tempBuf) !=0) {
                out.write(tempBuf);
            }
            out.flush() ;

è o mesmo problema anterior, o outputstrem fica esperando um fim de arquivo p/ terminar a leitura, porem, como vou mandar um fim de arquivo pro cliente?

Criado 12 de junho de 2006
Ultima resposta 14 de jun. de 2006
Respostas 7
Participantes 2