Dariusz Grębowiec

Dariusz Grębowiec Student,
Politechnika
Świętokrzyska w
Kielcach

Temat: strumienie, wątki i gniazda - problem

Witam wszystkich :)

Mam problem ze strumieniem wejściowym podczas odbierania obiektu po stronie klienta (aplikacja klient-serwer), a dokładniej wywala mi taki błąd:


java.io.StreamCorruptedException: invalid stream header: 7371007E
at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:783)
at java.io.ObjectInputStream.<init>(ObjectInputStream.java:280)
at klient.Polaczenie.run(Polaczenie.java:69)
at java.lang.Thread.run(Thread.java:619)


Poniżej zamieszczam fragmenty kodu, najpierw chciałbym dodać że problem dotyczy metody run() w klasie Polaczenie, oraz być może metody wyslijListeGraczy(int) w klasie PolaczenieSerwer

kod klasy Połączenie z pakietu klient:


public class Polaczenie implements Runnable {

private Socket klient = null;
private ObjectOutputStream wy;
private ObjectInputStream we;
private Paczka paczkaWe;
private ListaGraczy listaGraczy;
private Thread aktualizujListeThread = new Thread(this);
private HashMap<Integer, String> gracze = new HashMap<Integer, String>();
private String nick;
private String adres;

// SocketAddress socketAddress;

public Polaczenie(String nick, String adres, ListaGraczy listaGraczy)
throws UnknownHostException {
this.nick = nick;
this.adres = adres;
try {
klient = new Socket(adres, 4440);
} catch (IOException e) {
e.printStackTrace();
}
polacz();
this.listaGraczy = listaGraczy;

}

private void polacz() {
try {
wy = new ObjectOutputStream(klient.getOutputStream());
wy.writeObject(new Paczka(nick, adres));
wy.flush();

aktualizujListeThread.start();

} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
JOptionPane.showMessageDialog(null, "Problem z połączeniem...",
"BŁĄD SERWERA", JOptionPane.ERROR_MESSAGE);
}
}

public/* synchronized */void run() {

try {
while (true) {
//-------error---------------------
we = new ObjectInputStream(klient.getInputStream()); // linia nr 69
paczkaWe = (Paczka) we.readObject();
gracze = paczkaWe.getGracze();
System.out.println("aktualizaja listy graczy . . ." + gracze);
listaGraczy.dodajGracza(gracze);
}
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}

}
}


oraz fragment klasy działającej po stronie serwera:


public PolaczenieSerwer(int nrPortu) {
this.nrPortu = nrPortu;
try {
serwer = new ServerSocket(nrPortu);
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("oczekiwanie...");

while (true) {
podlaczGracza();
wyslijListeGraczy(/* gracze, */nrGracza);
nrGracza++;
}
}

void podlaczGracza() {
try {
klient = serwer.accept();
we = new ObjectInputStream(klient.getInputStream());
paczkaWe = (Paczka) we.readObject();
nick = paczkaWe.getNick();
gracze.put(nrGracza, nick);
System.out.println("dodano gracza: " + nick + ", nr: " + nrGracza);
graczeSocket.add(klient);

} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}

}

void wyslijListeGraczy(/* Gracze gracze, */int nrGracza) {
try {
graczeWy.add(new ObjectOutputStream(graczeSocket.get(nrGracza)
.getOutputStream()));
li = graczeWy.listIterator();
while (li.hasNext()) {

wy = li.next();
try {
wy.writeObject(new Paczka(gracze));
wy.flush();
System.out.println("*" + gracze);
} catch (IOException e) {
e.printStackTrace();
}

}

} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}


mam nadzieję, że nikogo nie zniechęci długość wątku:)

wszelkie wskazówki będą mile widziane;]Dariusz Grębowiec edytował(a) ten post dnia 07.02.10 o godzinie 17:21
Dariusz Grębowiec

Dariusz Grębowiec Student,
Politechnika
Świętokrzyska w
Kielcach

Temat: strumienie, wątki i gniazda - problem

dodam jeszcze, że błąd nie występuje gdy linię nr 70 czyli:

we = new ObjectInputStream(socket.getInputStream());


wstawię przed pętlą, ale wtedy otrzymywane dane są te same dla poszczególnych klientów:/Dariusz Grębowiec edytował(a) ten post dnia 07.02.10 o godzinie 22:10
Dariusz Grębowiec

Dariusz Grębowiec Student,
Politechnika
Świętokrzyska w
Kielcach

Temat: strumienie, wątki i gniazda - problem

problem rozwiązany:)

konto usunięte

Temat: strumienie, wątki i gniazda - problem

Dariusz Grębowiec:
problem rozwiązany:)

Mógłbyś, dla potomnych, napisać w czym tkwił problem:)
Dariusz Grębowiec

Dariusz Grębowiec Student,
Politechnika
Świętokrzyska w
Kielcach

Temat: strumienie, wątki i gniazda - problem

Problem tkwił w tym, że tworzyłem Listy z Socket ("graczeSocket") oraz ObjectOutputStream ("graczeWy") aby przemieszczać się między klientami, zamiast tworzyć np ArrayList z klasy która zawiera te wszystkie pola

Najlepiej umieszczę te klasy po przeróbce:

Zmieniła się tylko klasa PołączenieSerwer, oraz jest rozbita na dwie inne:

klasę Serwer


public class Serwer {

private ServerSocket serwer;
private ArrayList<Transport> serwerThread = new ArrayList<Transport>();
private Socket klient;
// private Thread watek1 = new Thread(this);
private ObjectInputStream we;
private Paczka paczkaWe;
private String nick;
ArrayList<String> gracze = new ArrayList<String>();
boolean start=true;
public Serwer() {
try {
serwer = new ServerSocket(4440);
//watek1.start();
while(true){
System.out.println("oczekiwanie na gracza...");
klient = serwer.accept();
pobierzDane();
serwerThread.add(new Transport(klient,nick));
//if(start)
//start=false;
Iterator<Transport> it = serwerThread.iterator();
while(it.hasNext()){
System.out.print("wysylana lista :"+gracze);
it.next().aktualizujListe(gracze);
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
void pobierzDane() {

try {
we = new ObjectInputStream(klient.getInputStream());
paczkaWe = (Paczka) we.readObject();
nick = paczkaWe.getNick();
System.out.println("gracz "+nick+" podlaczony");
gracze.add(nick);
} catch (IOException e) {

e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}

}
public static void main(String[] args) {
new Serwer();
}
}


oraz klasę Transport:


package serwer;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;

import java.util.ListIterator;

import wspolne.Paczka;

public class Transport/* extends Thread */{

private Socket klient;
private String nick;
private ObjectOutputStream wy;

public Transport(Socket klient ,String nick ) {
this.klient = klient;
this.nick=nick;
// watek.start();
}

void aktualizujListe(ArrayList<String> gracze){
try {
System.out.print("odebrana lista :"+gracze);
wy = new ObjectOutputStream(klient.getOutputStream());
wy.writeObject(new Paczka(gracze));
wy.flush();
System.out.println("*" + gracze);

} catch (IOException e) {
e.printStackTrace();
}
}

/*@Override
public void run() {

}
*/
ObjectOutputStream getWy() {
return wy;
}
String getNick(){
return nick;
}

}



Pewnie znalazło by się lepsze rozwiązanie, ale ważne że działa:)
Adam Woźniak

Adam Woźniak software architect
and developer

Temat: strumienie, wątki i gniazda - problem

Dariusz Grębowiec:
>

public class Serwer {[/quote]>[quote] void pobierzDane() {

try {
} catch (ClassNotFoundException e) {
e.printStackTrace();
}

Jesli chodzi o drobiazgi, to tu masz chyba typowe gotcha - mam na myśli obsługę wyjątków. Myślę, że nie powinieneś zjadać tutaj wyjątku (w bloku catch), a rzucać jego podobnie.
Jesli zjesz tu wyjątek, to 'nick' pozostanie null'em i, po chwili program oberwie NullPointerException przy próbie odwołań do owego 'nick'.

Pozdrawiam, Adam

konto usunięte

Temat: strumienie, wątki i gniazda - problem

W ogóle polecam zmienić sobie template na wyjątki w Eclipse. Dużo lepsze od printStackTrace() wydaje mi się np. opakowanie otrzymanego wyjątku w RuntimeException i rzucenie nim. Dzięki temu fragment kodu powodujący wyjątek kończy wykonywanie i de facto nie występują kolejne wyjątki. Masz jasność co się stało i dlaczego.
Dariusz Grębowiec

Dariusz Grębowiec Student,
Politechnika
Świętokrzyska w
Kielcach

Temat: strumienie, wątki i gniazda - problem

Adam Woźniak:
Jesli zjesz tu wyjątek, to 'nick' pozostanie null'em i, po chwili program oberwie NullPointerException przy próbie odwołań do owego 'nick'.

Pozdrawiam, Adam


nie wiedziałem, dzięki za zwrócenie uwagi:)
Dariusz Grębowiec

Dariusz Grębowiec Student,
Politechnika
Świętokrzyska w
Kielcach

Temat: strumienie, wątki i gniazda - problem

Dariusz Wawer:
W ogóle polecam zmienić sobie template na wyjątki w Eclipse. Dużo lepsze od printStackTrace() wydaje mi się np. opakowanie otrzymanego wyjątku w RuntimeException i rzucenie nim. Dzięki temu fragment kodu powodujący wyjątek kończy wykonywanie i de facto nie występują kolejne wyjątki. Masz jasność co się stało i dlaczego.


Nie bardzo rozumiem. Masz na myśli coś takiego?:


try{
try {
.
.
.
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}catch(RuntimeException re){
System.out.print("jakis blad");
}

konto usunięte

Temat: strumienie, wątki i gniazda - problem

try {
...
} catch (IOException e) {
throw new RuntimeException(e);
}
Dariusz Grębowiec

Dariusz Grębowiec Student,
Politechnika
Świętokrzyska w
Kielcach

Temat: strumienie, wątki i gniazda - problem

Dariusz Wawer:
try {
...
} catch (IOException e) {
throw new RuntimeException(e);
}

dzięki, na pewno skorzystam:)Dariusz Grębowiec edytował(a) ten post dnia 08.02.10 o godzinie 14:12

Następna dyskusja:

Problem z Web Service




Wyślij zaproszenie do