Pergunta

Estou construindo uma aplicação simples cliente / servidor utilizando soquetes de java e experimentar com a ObjectOutputStream etc.

Eu fui seguindo o tutorial no endereço http: //java.sun .com / desenvolvedor / technicalArticles / ALT / soquetes começando a meio caminho para baixo quando se fala sobre o transporte de objetos sobre soquetes.

Veja o meu código para o cliente http: // pastebin. com / m37e4c577 No entanto, este não parece trabalho e eu não consigo descobrir o que não está funcionando. O código comentado no fundo é copiado diretamente para fora do tutorial - e isso funciona quando eu apenas usar que em vez de criar o objeto cliente.

Alguém pode ver nada eu estou fazendo errado?

Foi útil?

Solução

O problema é a ordem que você está criando as correntes:

No servidor a partir do artigo (que eu suponho que é o que você está usando), quando uma nova conexão é aberta, o servidor abre pela primeira vez um fluxo de entrada, e, em seguida, um fluxo de saída:

public Connect(Socket clientSocket) {
 client = clientSocket;
 try {
  ois = new ObjectInputStream(client.getInputStream());
  oos = new ObjectOutputStream(client.getOutputStream());
 } catch(Exception e1) {
     // ...
 }
 this.start();
}

O código comentado exemplo utiliza a ordem inversa, primeiro, que estabelece o fluxo de saída, então o fluxo de entrada:

// open a socket connection
socket = new Socket("localhost", 2000);
// open I/O streams for objects
oos = new ObjectOutputStream(socket.getOutputStream());
ois = new ObjectInputStream(socket.getInputStream());

Mas o seu código faz o contrário:

server = new Socket(host, port);
in = new ObjectInputStream(server.getInputStream());
out = new ObjectOutputStream(server.getOutputStream());

O estabelecimento de um par fluxo de fluxo de saída / entrada vai parar até que eles trocaram suas informações aperto de mão, de modo que você deve coincidir com a ordem da criação. Você pode fazer isso apenas trocando as linhas 34 e 35 em seu código de exemplo.

Outras dicas

Você não está escrevendo o objeto em qualquer lugar.

Veja que apontam novamente, em algum lugar você tem que escrever:

 oos.writeObject( new Date() );

Em seu código você só tem

ois.readObject();

É por isso

Apenas um lembrete.

Quando você usa keep ObjectOutputStream em mente que ele mantém um cache de referência. Se você escrever um objeto, alterar o conteúdo de objetos e, em seguida, enviar o mesmo objeto novamente, você receberá os dados duplicados. Por exemplo:

List list = new ArrayList();
list.add("value1");
out.writeObject(list);
list.clear();
list.add("value2");
out.writeObject(list);

produzirá no lado do cliente duas listas com a string "value1".

Para evitar isso, o método de reposição deve ser invocado para redefinir o cache de fluxo ao escrever a mesma referência objeto várias vezes:

List list = new ArrayList();
list.add("value1");
out.writeObject(list);
out.reset();
list.clear();
list.add("value2");
out.writeObject(list);

Provavelmente você vai gostar de aprender o primeiro mais básico.

Aqui está um exemplo que acabo codificada.

É iniciar um servidor , que atende apenas um cliente e envia um objeto e morrer.

Quando o usuário pressionar (você) entra, uma nova cliente é criado, ele se conecta ao servidor criado anteriormente e ler o objeto que servidor irá enviar.

Sem exceção é tratada aqui. Apenas para tornar as coisas mais simples, mas esta não é a maneira de exceção deve ser tratada.

Quando você entender todos os conceitos aqui, será mais fácil de entender os do tutorial.

import java.io.*;
import java.net.*;
import java.util.*;

public class SimpleServer implements Runnable { 

     // Creates the server, send a "date" and die.
    public void run() { 
        try {
            ServerSocket server = new ServerSocket( 8090 );
            Date creationDate = new Date();
            System.out.println("(Server) Server is ready " 
                                 + "and running at " + creationDate );

            Socket uniqueClient = server.accept();

            // We will write using this "chained" object.
            ObjectOutputStream out = new ObjectOutputStream( 
                                                 uniqueClient.getOutputStream());

            out.writeObject( creationDate );


            // close all, at this point forget about the exceptions.
            // this is lesson #1      
            out.close();

            uniqueClient.close();

            server.close();        

            System.out.println("(Server) The server is down");
        }catch( IOException ioe ) {}

     }

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

         Thread serverThread = new Thread( new SimpleServer() );

         serverThread.start(); // start the server thread ... doh..

         System.out.println("(Client) Press enter when you want "+ 
                               " to connect to the server...");

         Scanner scanner = new Scanner( System.in );

         scanner.nextLine();

         Socket client = new Socket("localhost", 8090 );

         // Read from this object.
         ObjectInputStream in = new ObjectInputStream( client.getInputStream() );

         Date date = ( Date ) in.readObject();

         System.out.println("(Client) Current time is:          " + new Date() );
         System.out.println("(Client) Object read from server : " + date );

         in.close();
         client.close();

    }
}

Espero que isso ajude.

Se você tentou um depurador que teria lhe disse onde estava o problema. (Talvez não porque)

O problema que tenho é que ObjectOutputStream escreve um cabeçalho e ObjectInputStream lê esse cabeçalho. Você criou o ObjectInputStream primeiro que significa que ele está tentando ler um cabeçalho que nunca será escrita.

Solução:. Sempre criar o ObjectOutputStream primeiro e flush () antes de criar o ObjectInputStream

É melhor abrir uma outputStream porque um fluxo de saída não bloqueia. Então, você tem o fluxo de entrada que aguarda uma Stream. Depois de todos os fluxos, você gravar o fluxo e lave-lo - outputStream.flush() para enviar os bytes de dados. Você também vai precisar de um método na outra extremidade para ler a entrada, se é simplesmente inputStream.read() que lê cada byte como um inteiro para uma char, ou usando um BufferedReader ou Scanner. Eu usei quase todos os métodos possíveis, mas o método mais eficaz para o envio é outputStream.write(String) que escreve uma seqüência de chars como bytes na corrente e inputStream.read() leitura lê um único char. Espero que isso ajude.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top