Granny's Programming Pearls
"inside of every large program is a small program struggling to get out"
JavaRanch.com/granny.jsp
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

Socket and InputStream  RSS feed

 
Nicolas Viollin
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi !
I'am writting a MultiThread server for a game, and a MessageListener (here is the code):
package Commun.Messages;
import java.awt.Component;
import java.awt.Toolkit;
import java.awt.EventQueue;
import java.awt.AWTEvent;
import java.io.ObjectInputStream;
public class MessageManager extends Component implements Runnable{
private MessageListener messageListener;
private EventQueue evtq;
private java.io.InputStream is;
private boolean listen;

public MessageManager(){}

public MessageManager(java.io.InputStream is) throws Exception{
setInputStream(is);
prepareMessageManager();
}

public void setInputStream(java.io.InputStream is) throws Exception{
this.is = is;
}

private void prepareMessageManager(){
listen = true;
evtq = Toolkit.getDefaultToolkit().getSystemEventQueue();
enableEvents(0);
}
public void stop(){ listen = false; }

public void reset(){
}

public synchronized void addMessageListener(MessageListener ml) {
if (ml == null) return;
messageListener = MessageEventMulticaster.add(messageListener, ml);
}

public synchronized void removeMessageListener(MessageListener ml) {
if (ml == null) return;
messageListener = MessageEventMulticaster.remove(messageListener, ml);
}

public void processEvent(AWTEvent evt){
if (evt instanceof MessageEvent){
if (messageListener != null)
messageListener.messageReceived((MessageEvent)evt);
}else
super.processEvent(evt);
}

public void run(){
System.out.println("debut de run et preparation");
ObjectInputStream ois = null;
if (evtq != null){
Object obj = null;
int i = 0;
try{
/*------------ THERE IS THE PROB -----------------*/
ois = new ObjectInputStream(is);
}catch(Exception e){
e.printStackTrace();
}
while (listen){
try{
obj = ois.readObject();
if (obj instanceof Message){
MessageEvent me = new MessageEvent (this, (Message)obj);
evtq.postEvent(me);
}
}catch(Exception e){
if (!(e instanceof java.io.EOFException))
e.printStackTrace();
else
System.out.println("EOF " + i++);
}
}
}
}
}
the thing is the ObjectInputStream is only initialized when the socket receive data. but then i can't retreive the data transmitted
her is the client code side:
private void sendMessage(Message mess) throws Exception{
ObjectOutputStream oos = new ObjectOutputStream(soc.getOutputStream());
oos.writeObject(mess);
oos.flush();
/*------------ HERE IS THE PROB --------------*/
oos.close();
System.out.println("Socket closed ?: " + soc.isClosed());
}
where soc is the Socket. the prob is if I close the stream (oos.close()), it seems to close the socket as well, why ???

hope it's clear enought.
thnx
 
Barry Gaunt
Ranch Hand
Posts: 7729
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
From the API for ObjectOutputStream.close():
"This method must be called to release any resources associated with the stream". So it releases the resources by closing the socket too in your case.
I guess you will have to keep the ObjectOutputStream around (unless there is some attribute to prevent the release of the resource). Dunno, sorry.
BigBrother, please review the JavaRanch Naming Policy and change your displayed name accordingly (via your profile). Thanks
 
Barry Gaunt
Ranch Hand
Posts: 7729
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Just a thought, how about trying to subclass Socket and override the close method? You would have to find out a way of closing the socket when it's really required.
 
Barry Gaunt
Ranch Hand
Posts: 7729
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Two names Nico!!
 
Nicolas Viollin
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ok, thnx for your answers, it helps me to find where were my errors, now it's working quite well, but the prob is my server only received the first message sent by the client, and not the others.
Here is how it works, each connection from a client create a separate Thread (ClientManager) which then create a separate Thread (MessageManager) to listen to incomming messages.
Here is the code from the ClientManager:
public void run(){
run = true;
if (run){
addLogMessage("Dans le thread server, preparation MessageManager");
try{
mm = new MessageManager(clientSocket.getInputStream());
}catch(Exception e){
e.printStackTrace();
}
mm.addMessageListener(this);
Thread t = new Thread(mm);
t.start();
}
/* ------ HERE IS THE PROB I THINK ---------- */
}
and from the MessageManager:
public void run(){
System.out.println("debut de run et preparation");
ObjectInputStream ois = null;
if (evtq != null){
Object obj = null;
int i = 0;
try{
ois = new ObjectInputStream(is);
}catch(Exception e){
e.printStackTrace();
}
while (listen){
try{
obj = ois.readObject();
if (obj instanceof Message){
MessageEvent me = new MessageEvent (this, (Message)obj);
evtq.postEvent(me);
}
}catch(Exception e){
if (!(e instanceof java.io.EOFException))
e.getMessage();
else
System.out.println("EOF " + i++);
}
}
}
System.out.println("Fin de MessageManager");
}

I marked where i think the prob comes, the thread (ClientManager) died because the run() methode finishes, so How to avoid it ???
thnx !
PS: I've changed my name regarding the naming policy
 
Barry Gaunt
Ranch Hand
Posts: 7729
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If you want the ClientManager thread to wait until the MessageManager thread has finished you can do t.join() after the t.start().
Thanks for the name change Nico, keeps the "trail boss" happy.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!