I apologize in advance for the length of the note, and the source code
included.
I posted earlier under the title "Double streams", where i wanted to
use an RMI object as a sort of proxy for two clients to exchange data
via streams. I kinda failed, but now i'm trying something new. This
doesn't work either, but this time i think someone might be able to
solve it, since i'm not adept at using threads and i think that's
where the problem is. :)
The source for ByteHolder and RemoteByteHolde r is included below. A
server is run, making a ByteHolder, BH, available via RMI.
Client A obtains the reference to BH, and passes this on to its
FooOutputStream , which extends OutputStream and implements the
write(int b) method by calling putByte(b) on BH.
Client B also gets BH, passes this to FooInputStream, which extends
InputStream and implements read() by calling getByte() on BH.
What i did to test was:
- run the server
- client A wraps the FooOutputStream in a PrintWriter, and
println("foo") is called on it
- client B wraps FooInputStream in a InputStreamRead er, which is
then wrapped in a BufferedReader, and readLine() is called on that
The data then goes, one byte at the time, from client A to client B.
Client A stops running, but Client B just sorta hangs around... in a
deadlock i presume. I can make it return and print out the read line
by doing one of two things:
- kill the server
- manually send a -1 to client B
When i've used streams before, i didn't have to send a -1 in order to
get the reading side to get on with it - it just happened magically. I
also don't understand why killing the server make things better...
Can anyone explain this or, as an alternative, suggest a better way to
exchange bytes via RMI. I just really wanted to make streams work. :)
Oh, another thing. To make the server available, i've made it Runnable
and in the run i have a while(true) loop, that makes the thread sleep
for a chunk of time. Maybe that is a problem, too?
Regards,
Carsten H. Pedersen
----------- SOURCE BELOW -------------
package streams.holder;
import java.rmi.Remote ;
import java.rmi.Remote Exception;
public interface RemoteByteHolde r extends Remote {
int getByte() throws RemoteException ;
void putByte(int b) throws RemoteException ;
}
....
package streams.holder;
import java.rmi.Remote Exception;
public class ByteHolder implements RemoteByteHolde r {
private int theByte;
private boolean stored = false;
public synchronized int getByte() throws RemoteException {
while(!stored) {
try {
wait();
} catch (InterruptedExc eption e) {
// TODO Auto-generated catch block
e.printStackTra ce();
}
}
System.out.prin tln("hb: get: "+theByte);
int i = theByte;
stored = false;
notifyAll();
return i;
}
public synchronized void putByte(int b) throws RemoteException {
while(stored) {
try {
wait();
} catch (InterruptedExc eption e) {
// TODO Auto-generated catch block
e.printStackTra ce();
}
}
System.out.prin tln("bh: put: "+b);
stored = true;
theByte = b;
notifyAll();
}
}
included.
I posted earlier under the title "Double streams", where i wanted to
use an RMI object as a sort of proxy for two clients to exchange data
via streams. I kinda failed, but now i'm trying something new. This
doesn't work either, but this time i think someone might be able to
solve it, since i'm not adept at using threads and i think that's
where the problem is. :)
The source for ByteHolder and RemoteByteHolde r is included below. A
server is run, making a ByteHolder, BH, available via RMI.
Client A obtains the reference to BH, and passes this on to its
FooOutputStream , which extends OutputStream and implements the
write(int b) method by calling putByte(b) on BH.
Client B also gets BH, passes this to FooInputStream, which extends
InputStream and implements read() by calling getByte() on BH.
What i did to test was:
- run the server
- client A wraps the FooOutputStream in a PrintWriter, and
println("foo") is called on it
- client B wraps FooInputStream in a InputStreamRead er, which is
then wrapped in a BufferedReader, and readLine() is called on that
The data then goes, one byte at the time, from client A to client B.
Client A stops running, but Client B just sorta hangs around... in a
deadlock i presume. I can make it return and print out the read line
by doing one of two things:
- kill the server
- manually send a -1 to client B
When i've used streams before, i didn't have to send a -1 in order to
get the reading side to get on with it - it just happened magically. I
also don't understand why killing the server make things better...
Can anyone explain this or, as an alternative, suggest a better way to
exchange bytes via RMI. I just really wanted to make streams work. :)
Oh, another thing. To make the server available, i've made it Runnable
and in the run i have a while(true) loop, that makes the thread sleep
for a chunk of time. Maybe that is a problem, too?
Regards,
Carsten H. Pedersen
----------- SOURCE BELOW -------------
package streams.holder;
import java.rmi.Remote ;
import java.rmi.Remote Exception;
public interface RemoteByteHolde r extends Remote {
int getByte() throws RemoteException ;
void putByte(int b) throws RemoteException ;
}
....
package streams.holder;
import java.rmi.Remote Exception;
public class ByteHolder implements RemoteByteHolde r {
private int theByte;
private boolean stored = false;
public synchronized int getByte() throws RemoteException {
while(!stored) {
try {
wait();
} catch (InterruptedExc eption e) {
// TODO Auto-generated catch block
e.printStackTra ce();
}
}
System.out.prin tln("hb: get: "+theByte);
int i = theByte;
stored = false;
notifyAll();
return i;
}
public synchronized void putByte(int b) throws RemoteException {
while(stored) {
try {
wait();
} catch (InterruptedExc eption e) {
// TODO Auto-generated catch block
e.printStackTra ce();
}
}
System.out.prin tln("bh: put: "+b);
stored = true;
theByte = b;
notifyAll();
}
}
Comment