Serializacja - działa tylko raz?

0

Witam :)
Prost kod, który znajduje się poniżej, w pełni się kompiluje i uruchamia (wystarczy skopiować i uruchomić: najpierw serwer, potem klienta). Problem jednak w tym, że nie działa tak jak bym tego sobie życzył. A mianowicie:

Jest sobie serwer, który coś odbiera, a potem wysyła:

import java.io.*;
import java.net.*;
import java.util.logging.Level;
import java.util.logging.Logger;

public class SerwerTest {

    private Socket socket = null;
    private ServerSocket server = null;
    private ObjectOutputStream strumienObjOut;
    private ObjectInputStream strumienObjIn;
    private Dane dane = null;

    public SerwerTest() {
        try {
            //Tworzymy serwer (trzeba to uruchomić przed klientem)
            server = new ServerSocket(55777);
            System.out.println("Oczekiwanie na klienta...");
            socket = server.accept();
            System.out.println("Witamy klienta :)");
            dane = new Dane();
            //Serwer odbiera dane od klienta:
            strumienObjIn = new ObjectInputStream(socket.getInputStream());
            dane = (Dane) strumienObjIn.readObject();
            System.out.println("ODEBRANO_:_" + this.dane.getInstrukcja());

            dane = (Dane) strumienObjIn.readObject();
            System.out.println("ODEBRANO_:_" + this.dane.getInstrukcja());
            
            //Serwer mówi do klienta:
            strumienObjOut = new ObjectOutputStream(socket.getOutputStream());

            dane.setInstrukcja("Teraz serwer mówi pierwszy raz");
            strumienObjOut.writeObject(dane);
            strumienObjOut.flush();

            dane.setInstrukcja("Teraz serwer mówi ponownie");
            strumienObjOut.writeObject(dane);
            strumienObjOut.flush();

            strumienObjIn.close();
            strumienObjOut.close();
            socket.close();
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(SerwerTest.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ioe) {
            System.out.println(ioe);
        }
    }

    public static void main(String args[]) {
        SerwerTest server = new SerwerTest();
    }
}

Z serwerem łączy się klient, który coś wysyła, a potem odbiera od serwera:

import java.io.*;
import java.net.*;
import java.util.logging.Level;
import java.util.logging.Logger;

public class KlientTest {

    private Socket socket = null;
    private ObjectOutputStream strumienObjOut;
    private ObjectInputStream strumienObjIn;
    private Dane dane = null;

    public KlientTest() {
        try {
            //Klient łączy się z serwerem:
            socket = new Socket("localhost", 55777);
            System.out.println("Klient się połączył z serwerem");
            //Klient rozpoczyna nadawanie:            
            strumienObjOut = new ObjectOutputStream(socket.getOutputStream());
            dane = new Dane();
            
            dane.setInstrukcja("klient mówi pierwszy raz");
            strumienObjOut.writeObject(dane);
            strumienObjOut.flush();
            
            dane.setInstrukcja("klient mówi drugi raz");
            strumienObjOut.writeObject(dane);
            strumienObjOut.flush();
                        
            //Klient rozpoczyna nasłuchiwanie:  
            strumienObjIn = new ObjectInputStream(socket.getInputStream());
            
            dane = (Dane) strumienObjIn.readObject();
            System.out.println("ODEBRANO_:_" + this.dane.getInstrukcja());
            
            dane = (Dane) strumienObjIn.readObject();
            System.out.println("ODEBRANO_:_" + this.dane.getInstrukcja());
            
            strumienObjOut.close();
            strumienObjIn.close();
            socket.close();
            System.out.println("Koniec połączenia");
        } catch (ClassNotFoundException | IOException ex) {
            Logger.getLogger(KlientTest.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public static void main(String args[]) {
        KlientTest client = new KlientTest();
    }
}

A serializujemy obiekt klasy Dane:

import java.io.Serializable;
public class Dane implements Serializable {

    private String instrukcja;

    public Dane() {//konstruktor
        instrukcja = "Utworzono obiekt typu \"Dane\"";
    }

    public String getInstrukcja() {
        return this.instrukcja;
    }

    public void setInstrukcja(String instrukcja) {
        this.instrukcja = instrukcja;
    }
}

Niestety po uruchomieniu tego kodu otrzymujemy:
Po stronie serwera:

 Oczekiwanie na klienta...
Witamy klienta :)
ODEBRANO_:_klient mówi pierwszy raz
ODEBRANO_:_klient mówi pierwszy raz//błąd :(
BUILD SUCCESSFUL (total time: 2 seconds)

Po stronie klienta:

Klient się połączył z serwerem
ODEBRANO_:_Teraz serwer mówi pierwszy raz
ODEBRANO_:_Teraz serwer mówi pierwszy raz//błąd :(
Koniec połączenia
BUILD SUCCESSFUL (total time: 0 seconds) 

Co zrobić, aby przesłać ten sam obiekt więcej niż jeden raz? Poza tym, że za każdym razem można na nowo otwierać i zamykać połączenie. To jednak w moim przypadku jest bezużyteczne, mam bowiem serwer i wielu klientów (w pełnej wersji tego kodu). Jeżeli użytkownik 1 łączy się z serwerem i coś wysyła, po czym zrywa połączenie, to jak ma odebrać kolejną wiadomość od serwera? Musi być stale na nasłuchu.

Czego próbowałem:
-zamykać i otwierać na nowo tylko strumienie, ale to od razu zamyka też socket'a, przez co ponowne otwarcie strumienia kończy się błędem.
-korzystać z bufora, ale to wygenerowało mi tylko więcej nieoczekiwanych zachowań ;)

Nie wiem co jest tutaj źle. Siedzę nad tym już 5 dzień z rzędu. Z góry dziękuję za pomoc.

7

Dodaj wywołanie reset(), np.

dane.setInstrukcja("klient mówi drugi raz");
strumienObjOut.reset();
strumienObjOut.writeObject(dane);
strumienObjOut.flush();
1

Serializacja 'zapamietuje' ktore obiekty juz zostaly zapisane, i jestl ten sam obiekt jest pisany drugi raz, pisany jest tylko 'handle' do niego, i po stronie czytajacej odczytywany jest 'stary', zapamietany obiekt. Rozwiazanie bogdansa jest dobre. @bogdans - zdziwilbys sie jak malo osob to wie - az sie zaloguje i dam plusa ;d

0

DZIAŁA! Biję pokłony do ziemi, mój wielki problem został rozwiązany. Dziękuję!

1 użytkowników online, w tym zalogowanych: 0, gości: 1