problem med ObjectInputStream i java

Permalänk

problem med ObjectInputStream i java

Hej jag använder en ObjectInputStream(InputStream in) på en socket för att läsa objekt. Innan jag läsar vill jag kolla om det finns data att läsa.

Anledningen till detta är att jag har flera socketar och om man läser så stannar readObject metoden på den socketen den fick in data på sist.

Innan så använda jag en BufferedReader och metoden

ready()
Tell whether this stream is ready to be read.

det är en sådan metod jag vill ha fast på en ObjectInputStream.

Anlednigen till att jag har gått från att använda BufferedReader är att jag vill kunna skicka och läsa object och inte bara strängar.

Det går inte så bra att klistra in koden här men om ni ger mig något ställa att upploada koden på så kan ni få se den felande metoden.

Och språket är java, om ni inte försog det!

Permalänk
Medlem

Jag har inget svar just nu på din fråga, men låter du samma tråd ha hand om alla kopplingar? Oftast brukar man ju skapa en ny tråd för varje ny uppkoppling:

Socket s = serverSocket.accept(); new ReaderThread( s ).start();

Visa signatur

Fame's a bitch, man

Permalänk

Jag har hört att man inte ska ha en tråd per användare tar upp mycket datorkraft. I stället har jag en tråd som tar emot anslutningar. En tråd som kollar efter objekt, när det hittar ett meddelande väcker den sovande tråd ur en trådpool. Tråden skickar iväg objektet och när den är klar med det går den över till att sova igen. På detta sättet optemerar jag antalet trådar i programmmer och det tar mindre datorkraft.

Vist skulle jag kunna lösa problemmet med en tråd per ansluten användare men jag vill hellre ha någon annan metod, har gått ifrån en sådan struktur känns dumt att gå tillbaka i utvecklingen.

Tack för hjälpen ialla fall.

Permalänk
3dfx Fanboy

Har aldrig använt ObjInpStr i samband med sockets... men kan man inte använda available()?

if (ois.available() > 0)
//read?

Osäker..

I vilket fall som helst så går det det utmärkt att lösa problemet med BufferedReader om du serialiserar/deserialiserar objekten med hjälp av xml..

ang. "trådar per socket" så är det naturligtvis bättre (mer effektivt) att ha en SocketPool och låta en enda tråd att vandra över alla sockets..

Visa signatur

Runnin with a pump pump
no bluffin we buck buck

Permalänk

ois.available() > 0 har jag inte fått att funka, den verkar alltid vara 0 konstigt. Men om man kan använda en BufferedReader så är det löst ju. Jag vill kunna skicka ett image objekt kan man alltså sicka ett sådant om man deserialiserar det.

Har du något kod exempel på hur man gör för att serialiserar/deserialiserar objekten?

Permalänk
3dfx Fanboy
Citat:

Ursprungligen inskrivet av mikaelkrantz
ois.available() > 0 har jag inte fått att funka, den verkar alltid vara 0 konstigt. Men om man kan använda en BufferedReader så är det löst ju. Jag vill kunna skicka ett image objekt kan man alltså sicka ett sådant om man deserialiserar det.

Har du något kod exempel på hur man gör för att serialiserar/deserialiserar objekten?

posta gärna exempel på hur du löst det hela med sockets.. efter att du har fått ett inkommande anrop så ska väl det vara ok att ta emot bilden? i så fall så borde det ju finnas data att läsa?

Vad gör applikationen? det låter som någon slags webcam sak? I så fall så vill du kanske skippa TCP och köra med datagram?

Att skicka över bilden med xml är dock inte att föredra..

Visa signatur

Runnin with a pump pump
no bluffin we buck buck

Permalänk

Det är ett pictonary spel, problemmet är inte att det inte går att läsa data utan att programmet låser sig på den första socketen den fick data på. För att få den att gå vidare i loopen måste den få in data på den socketen den väntar på. Det innebär att om client A sickar data så kommer det fram, men om sedan B sickar det så kommer det inte fram förän A har skickat data igen.

Du kanse försår, men om det går att serialiserar ett image objekt och skicka det som en sträng med bufferedread så är det hela löst.

public void run()
{

System.out.println("run()");

ComThread comThread;

while(true)
{
try
{
processThread.sleep(400);

Object o2Send;
o2Send = this.checkMsg();

if(o2Send != null)
{
System.out.println(o2Send);

comThread = threadPool.freeThread();

comThread.sendMsg(o2Send, index);
}

}

catch(Exception e) {System.out.println(e);}

}
}

public Object checkMsg() //check all client sockets in the array for messages
{
Object transferedData = null;
int check = 0; //you dont won't to send out the key words to all users,

for(int i = 0; i<observer.player.length;i++)
{

try
{

if(observer.player[i].getIn() != null) {

if(observer.player[i].isFree() == false)
{
ObjectInputStream ois = observer.player[i].getIn();
transferedData = ois.readObject();

check = observer.checkMsg(transferedData,i);

index = i;
}

}
}
catch(IOException e) {System.out.println(e);}
catch(ClassNotFoundException e1) {System.out.println(e1);}
}

if(check != Observer.KEYWORD)
{
return transferedData;
}

else
return null;
}

det blir inte vackert om man infogar kod här.

Nu ser du ialla fall metoden som checkar data och tråden som kör metoden och anropar trådpolen.

Permalänk
3dfx Fanboy

if(observer.player[i].getIn() != null) {
if(observer.player[i].isFree() == false) {

Det är dessa två som jag är lite förvirrad över..

Varför null-check på ois överhuvudtaget?

Vad gör isFree-metoden? Verkar vara ologiskt att fortsätta inläsningen om isFree? --> false... Om den inte är ledig så är den väl upptagen eller ngt?

Förstår inte heller hur programmet är uppbyggt egentligen eftersom det "känns" som om du kör med konstanta socket <---> socket förbindelser mellan klienterna och servern..

Varför inte låta klienterna att alltid anropa mot en och samma serversocket? då vet du att du kommer exekvera inläsningen enbart om det finns data på ingång...?

Med andra ord:

Istället för att loopa över öppna sockets och kolla om det finns data, så låt alla klienter att anropa mot samma serversocket.. om ett sådant anrop dyker upp så använder du dig av ThreadPool:en för att berbeta den inkommande datan..

Visa signatur

Runnin with a pump pump
no bluffin we buck buck