Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Java Development

Reply
Developer
Posts: 54
Registered: ‎05-28-2009
My Device: Not Specified
Accepted Solution

Bytes and Direct connection

Hi guys,

we have a C++ TCP/IP Application running on windows , when the blackberry connect to this application it should send first an ID like "1010420001" to this application using Direct connection

if I try like this:

String  str = "úø!É9<";
                char c1 = str.charAt(0);
                byte bValue1 = (byte)c1;
                char c2 = str.charAt(1);
                byte bValue2 = (byte)c2;
                char c3 = str.charAt(2);
                byte bValue3 = (byte)c3;
                char c4 = str.charAt(3);
                byte bValue4 = (byte)c4;
                char c5 = str.charAt(4);
                byte bValue5 = (byte)c5;
                char c6 = str.charAt(5);
                byte bValue6 = (byte)c6;
                char c7 = str.charAt(6);
                byte bValue7 = (byte)c7;
                char c8 = str.charAt(7);
                byte bValue8 = (byte)c8;               
                byte[] anArray = new byte[10];
                anArray[0] = bValue1;
                anArray[1] = bValue2;
                anArray[2] = bValue3;
                anArray[3] = bValue4;
                anArray[4] = bValue5;
                anArray[5] = bValue6;
                anArray[6] = bValue7;
                anArray[7] = bValue8;
                try{
                        conn = (StreamConnection)Connector.open(URL);
                        DataOutputStream os = conn.openDataOutputStream();
                        os.write(anArray);
                }
                catch(Exception g){}

 

 

 

I receive it on the server application,

but i have problems  sending it like this:

 

private void exchange(String data) throws IOException
        {
            int length = data.length();
            char[] input = new char[length];
            _out.write(data, 0, length)
            for (int i = 0; i < length; ++i)
            {
                input[i] = (char)_in.read();
            }
            StringBuffer s = new StringBuffer();
            s.append("Received: ") ;
            s.append(input, 0, length);
            updateDisplay(s.toString());
        }
      
        public void run()
        {
            try
            {
                updateDisplay("Opening Connection...");
                connection = (StreamConnection)Connector.open(URL);
                updateDisplay("Connection open");
                _in = new InputStreamReader(connection.openInputStream());
                _out = new OutputStreamWriter(connection.openOutputStream());
                char[] input = new char[1024];
                exchange("1010420001");
                updateDisplay("Done!");
            }
            catch(IOException e)
            {
                System.err.println(e.toString());
            }

 

 

what can be done?how to change the second one to send array of bytes like the first one??

 

Thanks

Developer
Posts: 52
Registered: ‎07-17-2008
My Device: Not Specified

Re: Bytes and Direct connection

You could try:

 

byte[] data = new byte[str.length()];

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

    data[i] = (byte) str.charAt(i);

}

 

try{
  conn = (StreamConnection)Connector.open(URL);
  DataOutputStream os = conn.openDataOutputStream();
  os.write(data);
}
catch(IOException g){ //You really don't wanna catch generic exceptions!

  //You really should log or do something here

}

 

Though I don't see why this wouldn't work either:

try{
  conn = (StreamConnection)Connector.open(URL);
  DataOutputStream os = conn.openDataOutputStream();
  os.writeChars(str);
}
catch(IOException g){ //You really don't wanna catch generic exceptions!

  //You really should log or do something here

}

 

Then again... I bet you just need to add a flush to your original code that uses the OutputStreamWriter. If the data's just not going then the flush should work. If the data is going downstream but being interpreted wrong then you should double check both the encodings on your target and destination platforms and possibly the endianess of both. I can tell you from experience that C under OSX uses a different endian than Java running on Linux. If its numerics encoded in the string being interpreted incorrectly on the recipientas numbers than a simplehigh to low order byte swapy would do in the C code

Developer
Posts: 54
Registered: ‎05-28-2009
My Device: Not Specified

Re: Bytes and Direct connection

this one is working:

try{
  conn = (StreamConnection)Connector.open(URL);
  DataOutputStream os = conn.openDataOutputStream();
  os.writeChars(str);
}
catch(IOException g){ //You really don't wanna catch generic exceptions!

  //You really should log or do something here

}

 

 

but I need to  send data after the handshaking so after sending the id i would like to send a string :

 

 connection = (StreamConnection)Connector.open(URL);
_in = new InputStreamReader(connection.openInputStream());
 _out = new OutputStreamWriter(connection.openOutputStream(),"UTF-8");

String data = "TEST_TEST_TEST_TEST";
char[] input = new char[1024];

 int length = data.length();         
char[] input = new char[length];
_out.write(data, 0, length);         
for (int i = 0; i < length; ++i) // Pre-increment is more efficient, as is caching the loop invariant.
     {
        input[i] = (char)_in.read();
      }  

 

I want to use     DataOutputStream  or      OutputStreamWriter? and not both
         

thanks

Developer
Posts: 52
Registered: ‎07-17-2008
My Device: Not Specified

Re: Bytes and Direct connection

I'm still not sure why the OutputStreamWriter wasn't working. In general, you always want to use writers for sending text and raw streams for sending binary (images, audio, video, etc.). DataOutputStream is one of those hacks that just feels wrong to me but always seems to work when others fail. You also want to be very careful with using a writer and a stream. In other words something like this can get you into trouble:

 

OutputStream os = getOutputStreamFromSomewhere();

Writer writer = createWriterAroundStream(os)

 

writer.write(someText) ;

new DataOutputStream(os).writeChars(someOtherText);

 

The problem is that buffering can occur in the writer causing some of the text to write while the later code writes more to the same stream causing interpolation of the text. Most often times adding a flush after you've written to a writer or stream will ensure the data makes it to its intended destination. When in doubt, use the analogy of a toilet. (Yes its disgusting but it helps.) Your server would be like the sewer while the stream or writer would be the toilet. If your app pours last night's uneaten vegetables (the ones that were left out and are now stinking up the house) in the toilet the sewer doesn't necessarily get them. However if you flush the toilet (your stream or writer) then the sewer would enjoy the benefit of day old broccoli.

 

You never did say why your first example wasn't working. I'm assuming you were missing a flush but if the data was actually going to the server with the wrong encoding then I'm using the wrong analogy to explain the situation.

Developer
Posts: 54
Registered: ‎05-28-2009
My Device: Not Specified

Re: Bytes and Direct connection

Hi, OutputStreamWriter  is working perfectly,

Let me change the way I put the question, the question is

 

How do I send Bytes  using OutputStreamWriter ??

 

Thanks Guys for your help

Developer
Posts: 52
Registered: ‎07-17-2008
My Device: Not Specified

Re: Bytes and Direct connection

You don't want to send bytes with a writer, it defeats the purpose. Writers are meant for sending text whereas bytse should be sent directly to the output stream. You have to forget the deatils and consider your overall objective. If you have text, like an XML document or an email that needs to travel from one place to another then you want to use a writer and not worry about how it sends the individual bytes. Trying to understand and control how a writer works interally will only add complexity whereas you only really want text to be sent. If you are sending media (images, audio, video, etc) then you never want to use a writer. Writers have a way of munging binary data as they are designed for text/strings. With binary media files you want to write the bytes directly to the output stream and in all cases make sure you flush.

 

that said, there may be times when you'll want to send both. In our project we sometimes send text followed by binary data. (It's not a practice that I'm fond of.) In these cases see my above post about using a writer and a stream. It's dangerous, but acheivable as long as you flush in between usages. Returning to the toilet analogy you wouldn't want to use the bowl after someone else if they didn't flush. So consider you want to send "hello world" followed by a PNG image of the planet to the server. You would wrap your outputstream with a Writer and call:

//Assuming outputStream is attached to a server

Writer writer = new OutputStreamWriter(outputStream);

writer.write("Hello World");

writer.flush();

InputStream input = //read png from SD card or whatever

for(int theNextByte = input.read(); theNextByte != -1; theNextByte = input.read()) outputStream.write(theNextByte);

outputStream.flush();

outputStream.close(); // do not use outputstream after this point

 

 

Your server would then receive the text "Hello World" followed by a png graphic of the planet. That's a rough example and typically you would want to read/write in blocks rather than a byte at a time but I didn't want to drag the example out too much.

Developer
Posts: 54
Registered: ‎05-28-2009
My Device: Not Specified

Re: Bytes and Direct connection

did u try it on Blackberry? it didnt work on mine?

??

Developer
Posts: 52
Registered: ‎07-17-2008
My Device: Not Specified

Re: Bytes and Direct connection

I've done this a while ago and unfortunately I don't have any code on hand that I could use to validate. (I'm just now returning to Blakckberry after a year long hiatus with iPhone dev.) Could you explain what's not working for you? Are you getting text mixed in with binary? Can you report what the sever actually receives? A good way to test is to post to a mock or test servlet. you can do this from home by visiting whatsmyip.org, writing down your IP address, opening up a port on your router (port 80 or 8080 for a tomcat or jetty instance) and running a hack servlet under Tomcat or Jetty in debug. Point your phone (with the app installed) to the ip address and inspect the values in the debugger.
Developer
Posts: 709
Registered: ‎09-10-2009
My Device: 8520, 8900, 9000, 9300, 9650, 9700, 9780, 9800, 9810, 9900, 9930
My Carrier: Verizon

Re: Bytes and Direct connection

I would send everything in text and don't worry about the extra bandwidth requirement. It is much easier to port the apps to a different platform. For binary data, put them in a byte array and send them direct to the output stream and don't use a writer.
Developer
Posts: 54
Registered: ‎05-28-2009
My Device: Not Specified

Re: Bytes and Direct connection

those aremy steps:

1. connect to a server

2. send 10 bytes as a synchronization message to the server

3. send string every 2 minutes to the server

 

anyone can help ?