Problema com ObjectInputStream em socket's

3 respostas
P

Tenho um servidor, que apos aceitar conexoes de clientes, ele cria uma thread.
Nessa thread eu tenho um BufferedReader e um ObjectOutputStream.
O primeiro serve para receber um comando que indica o que o cliente está requisitando.
O segundo envia o objeto que o cliente está requisitando.

Até ai, nao tive problema nenhum. Porem chegou uma hora no meu trabalho, que eu tive que fazer o cliente enviar um objeto pro servidor.
Então criei um ObjectInputStream para receber esse objeto.
Porém, na hora que o cliente conecta ao servidor, esse ObjectInputStream não consegue ser instanciado. Acontece uma excessao: Stream Corrupted.

O codigo da thread:
public class ThreadConexaoCliente extends Thread {
	private Socket socket;
	private BufferedReader inComando;
	private ObjectOutputStream outObject;
	//private ObjectInputStream inObject;
	
	public ThreadConexaoCliente(Socket s) {
		socket = s;
		try {
			//Nao to conseguindo instanciar esse inObject!!!!!!!!!!!!!!
			inComando = new BufferedReader(new InputStreamReader(socket.getInputStream()));
			outObject = new ObjectOutputStream(socket.getOutputStream());
			//inObject = new ObjectInputStream(socket.getInputStream());
		} catch (IOException exception) {
			exception.printStackTrace();
			JOptionPane.showMessageDialog(null, "Erro ao construir Thread de conexao");
		}
	}
	
	public void run() {
		try {
			while(true) {
				String comando = null;
				System.out.println("Esperando comando...");
				while (comando == null)
					comando = inComando.readLine();
				System.out.println(comando);
				
				
				if (comando.compareToIgnoreCase("close") == 0) {
					System.out.println("Fechou conexao");
					socket.close();
					break;
					
				} else if (comando.compareToIgnoreCase("ReceberInfoUrna") == 0) {
					//Le chave privada
					ObjectInputStream inKey = new ObjectInputStream(new FileInputStream("privadaServidor.key"));
					PrivateKey chavePrivada = (PrivateKey) inKey.readObject();
					inKey.close();
					
					//Assina infoUrnas
					Signature assinador = Signature.getInstance("DSA");
					assinador.initSign(chavePrivada);
					InfoUrna infoUrnas[] = new LoaderInfoUrna().loadInfo();
					SignedObject infoUrnasAssinado = new SignedObject(infoUrnas, chavePrivada, assinador);
					
					//Enviar infoUrnasAssinado
					outObject.writeObject(infoUrnasAssinado);
					outObject.flush();
					
				} else if (comando.compareToIgnoreCase("ReceberInfoCandidatos") == 0) {
					InfoCandidatos.enviaInfoCandidatos(outObject);
					
				} else if (comando.compareToIgnoreCase("EnviarResumo") == 0) {
					//falta implementar
					
				} else if (comando.compareToIgnoreCase("ChavePublica") == 0) {
					//falta implementar
					
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
			JOptionPane.showMessageDialog(null, "Erro ao fechar socket");
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (InvalidKeyException e) {
			e.printStackTrace();
		} catch (SignatureException e) {
			e.printStackTrace();
		}
	}

}
O Codigo do cliente:
private static String conectaServidor(String ip) {
		try {
			Socket socket = new Socket(ip, URNA_PORT);
			
			PrintWriter out = new PrintWriter(socket.getOutputStream());
			ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
			
			receberInfoUrna(out, in);
			receberInfoCandidatos(out, in);
			
			out.println("close");
			out.flush();
			socket.close();
			
		} catch (IOException exception) {
			JOptionPane.showMessageDialog(null, "Erro ao conectar-se com o servidor", "Erro!", JOptionPane.ERROR_MESSAGE);
		} catch (ClassNotFoundException exception) {
			exception.printStackTrace();
		} catch (InvalidKeyException e) {
			e.printStackTrace();
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (SignatureException e) {
			e.printStackTrace();
		}
		
		return null;
	}

3 Respostas

P

up

Marcelo_FS

Acredito que você não possa ter dois objetos lendo do mesmo InputStream; você terá dois objetos chamando input.read(), o que causará a corrupção de dados em um deles (ou em ambos?).

Você pode ou utilizar somente o ObjectInputStream (alterando seu código já existente) ou criar outra conexão por parte do cliente somente para passar o objeto que vc precisa…

P

Obrigado MarceloS.

Ao invez de ter um input para ler String, e outro para ler Object.
Deixei só o Object, e faco a coersão para String.
Assim passou a funcionar.

Criado 29 de novembro de 2008
Ultima resposta 6 de dez. de 2008
Respostas 3
Participantes 2