Java Bluetooth API + Stream limitation

J

JScoobyCed

Hi,

This is a follow up to my previous post about input/outputstreams.
I am now sure that my code is able to read correctly the byte coming on
the Stream (InputStream or DataInputStream).
The strange behaviour is that it blocks after reading a specific amount
of data, whatever the content is (See code at the end of the post).

The first 4 byte writen/read is the size of data to transfert. No
problem with that part.
On the DataOutputStream, I use dos.write(data,0,data.length);
On the DataInputStream, I loop to read dis.read(tmp,0,nextLen());
( nextLen() returns the default packet size to read (1024), or the
remaining amount of data if less than 1024 )

Case 1. The "test" data sent is:
byte[] data = new byte[20000];
for(int i=0; i<data.length;i++)
data = (byte) i;

--> Result: I receive correctly the whole 20000 bytes

Case 2. The "test" data sent is:
byte[] data = new byte[35000];
for(int i=0; i<data.length;i++)
data = (byte) i;

--> Result: I receive only 20480 bytes, and the last 1024 bytes of the
array are not correct

Case 3. The real data sent is:
byte[] data = videoControl.getSnapshot(null);
( this will return a PNG image as a byte[], approx 37500 Kb)

--> Result: I receive only 20480 bytes, and the last 1024 bytes of the
array are not correct

Now, the Stream are open between a Mobile Phone having the JSR82
BlueTooth API, and a computer having the BlueCove JSR82 BlueTooth API
(under windows XP SP2).
Is there any limitation in the size?
Is my code doing something wrong ?

Thank you.




Here is the two Objects that manage the streams:
<OutputStreamWriter>

public class OutputStreamWriter {

private DataOutputStream os;

public OutputStreamWriter(OutputStream os) {
this.os = new DataOutputStream(os);
}

public int writeString(String str) {
return writeByte(str.getBytes());
}

public int writeByte(byte[] data) {
int ret = -1;
try {
os.write(Converter.intToBytes(data.length));
os.write(data,0,data.length);
os.flush();
ret = 0;
} catch (IOException ioe) {
ret = -2;
} catch (NullPointerException npe) {
ret = -3;
} catch (Exception exc) {
}
return ret;
}

public void close() {
try {
os.flush();
os.close();
os = null;
} catch (Exception exc) {
}
}
}
</OutputStreamWriter>

<InputStreamReader>

public class InputStreamReader implements Runnable {

private DataInputStream is;
private boolean running;
private IOListener iolist;
private final int defLen = 1024;
private int size = 0;
private int read = 0;
private byte[] data;

public InputStreamReader(InputStream is, IOListener iol) {
this.is = new DataInputStream(is);
iolist = iol;
}

private int readSize() {
byte[] bSize = new byte[4];
try {
is.read(bSize);
read = 0;
} catch (Exception exc) {
}
return Converter.bytesToInt(bSize);
}

public byte[] readByte() {
int si = nextLen();
byte[] by = new byte[si];
int cur = 0;
try {
cur = is.read(by, 0, si);
} catch (IOException ioe) {
running = false;
} catch (Exception exc) {
running = false;
}
read += cur;
return by;
}

private int nextLen() {
int len = size - data.length;
int ret = len;
if (len > defLen)
ret = defLen;
return ret;
}

public void run() {
running = true;
while (running) {
if (size == 0) {
size = readSize();
System.out.println("Waiting: " + size);
read = 0;
data = new byte[0];
if (size == 0)
break;
}
byte[] by = readByte();
if (by != null) {
if (by.length > 0) {
append(by);
}
}
try {
Thread.sleep(5);
Thread.yield();
} catch (Exception exc) {
}
}
push();
}

private void append(byte[] b) {
data = ByteUtility.merge(data, b);
if (data.length == size) {
push();
}
}

private void push() {
if (data.length > 0) {
IOEvent ev = new IOEvent(data, data.length, IOEvent.INPUT);
data = new byte[0];
size = 0;
iolist.IOMessage(ev);
}
}

public void stop() {
running = false;
}

public void close() {
stop();
try {
is.close();
is = null;
} catch (Exception exc) {
}
}
}
</InputStreamReader>
 
L

Lee Fesperman

JScoobyCed said:
This is a follow up to my previous post about input/outputstreams.
I am now sure that my code is able to read correctly the byte coming on
the Stream (InputStream or DataInputStream).
The strange behaviour is that it blocks after reading a specific amount
of data, whatever the content is (See code at the end of the post).

You really shouldn't start another thread on the same topic, but I have a few comments
on your code.

You are using read() incorrectly in your code. read() is not guaranteed to read the full
length specified, even if end-of-stream is not encountered. It returns the # of bytes
actually read. You need to use the returned # of bytes in your code. Otherwise, you will
get the 'strange' behaviour you indicated.

Also, your use of InputStreamReader and OutputStreamWriter for your class names is a
very bad choice. Both are names of classes in java.io. Reusing standard class names
makes your code confusing.
 
J

JScoobyCed

Lee said:
You really shouldn't start another thread on the same topic, but I have a few comments
on your code.

You are using read() incorrectly in your code. read() is not guaranteed to read the full
length specified, even if end-of-stream is not encountered. It returns the # of bytes
actually read. You need to use the returned # of bytes in your code. Otherwise, you will
get the 'strange' behaviour you indicated.

Also, your use of InputStreamReader and OutputStreamWriter for your class names is a
very bad choice. Both are names of classes in java.io. Reusing standard class names
makes your code confusing.

Thank you for your output.
The fact I started a new Thread is because the question was more
specific, and not the same Class concern.
Your mention about the read() method is right. At some time of my tests,
I was checking the returned value, but sometines I removed it for
other purpose (and I really shouldn't have :))
Yeah, I know about the name of my two classes. I was just because their
name was really explicit. I will ask Sun to change their two class names
to something different from mine ;) When I have finished my code I will
rename many classes in my packages. I have other similar classes that
reuse existing names :)

BTW, I have found the problem. The fact I wasn't able to receive
complete data was linked to the BT communication.
I now send by bunches of 360 bytes for big size data, and 1024 for
smaller size of data ( < 35 Kb)
I will refine this scall to optimize the transfert of data depending on
the size.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,014
Latest member
BiancaFix3

Latest Threads

Top