Welcome to the Official BlackBerry® Support Community Forums. This is your resource to discuss support topics with your peers, and learn from each other. New to the forum? Please visit the ‘Getting Started’ link below.
inside custom component

Java Development

Reply
New Developer
maltic
Posts: 49
Registered: 09-25-2009

TCP connections suck ... any of them

Hi,

 

I am new the BB programming and as you can see in my other posts I am trying to transfer data from a PC to a Blackberry. I tried webservices (too complicated, integration with .NET webservices faulty), so I moved to Socket connections. From that I learned that I have to care about the protocol, e.g. error correcting, flow control etc myself. I wrote some kind of simple protocol but sometimes got the problem that the connection simply "hangs".

 

I am using a BB 8900, JDE 4.6.1 and a direct connection via WIFI, C# 2008 on W7 on the other side.

 

I did not want to give up, so I tried HTTP connections - hooray - lots of my code is not important anymore, so I can post my short apps here:

 

C# server side

 

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net; using System.Threading; using System.IO; namespace FileSyncer2 { class Program { static void Main(string[] args) { HttpListener oHttpListener = new HttpListener(); oHttpListener.Prefixes.Add("http://192.168.42.2:8080/"); oHttpListener.Start(); Console.WriteLine("Listener started"); for (;;) { HttpListenerContext oContext = oHttpListener.GetContext(); new Thread(new Worker(oContext).ProcessRequest).Start(); } } class Worker { private HttpListenerContext oContext; public Worker(HttpListenerContext oContext) { this.oContext = oContext; } public void ProcessRequest() { string msg = oContext.Request.HttpMethod + " " + oContext.Request.Url + " " + oContext.Request.RawUrl; Console.WriteLine(msg); oContext.Response.StatusCode = (int)HttpStatusCode.OK; byte[] vBuffer = new byte[409600]; oContext.Response.ContentLength64 = new FileInfo("C:\\dummyfile.bin").Length; FileStream oSR = new FileStream("C:\\dummyfile.bin", FileMode.Open); BinaryReader oBR = new BinaryReader(oSR); int vReadBytes = -1; Stream oStream = oContext.Response.OutputStream; while (vReadBytes != 0) { vReadBytes = oBR.Read(vBuffer, 0, 409600); if (vReadBytes != 0) try { oStream.Write(vBuffer, 0, vReadBytes); } catch (Exception ex) { Console.WriteLine(ex.Message); } Console.WriteLine("Still Reading..."); } oStream.Close(); oStream.Dispose(); oBR.Close(); oSR.Close(); } } } } }

 

 

This does not seem to be too complicated, I am listening for a GET request on port 8080 and for any request I am sending the dummy file.

 

Now for the Blackberry part:

 

HttpConnection httpConnection = (HttpConnection) Connector.open("http://192.168.42.2:8080/dummyfile.bin;deviceside=true;interface=wifi", Connector.READ_WRITE); httpConnection.setRequestMethod(HttpConnection.GET); int responseCode = httpConnection.getResponseCode(); if (responseCode == HttpConnection.HTTP_OK) { InputStream inputStream = httpConnection.openInputStream(); FileConnection oFileConnection = (FileConnection)Connector.open("file:///SDCard/Blackberry/music/dummyfile.bin",Connector.READ_WRITE); if (oFileConnection.exists()) oFileConnection.delete(); long vTotal=httpConnection.getLength(); oFileConnection.create(); OutputStream oFileOutputStream = oFileConnection.openOutputStream(); byte[] vBuffer = new byte[102400]; int vLength=0; long vRead=0; while (-1 != (vLength = inputStream.read(vBuffer))) { oFileOutputStream.write(vBuffer, 0, vLength); vRead+=vLength; oGaugeField.setValue((int)net.rim.device.api.util.MathUtilities.round(100.0/vTotal*vRead)); } httpConnection.close(); oFileOutputStream.close(); oFileConnection.close(); }

 

 

That´s not too complicated as well. I put this in a loop and sometimes at the first try and sometimes later the progress simply stops. It then throws an exception at the c# code at oStream.Close(), but the progress bar is still somewhere between 0 and 100.

 

I´ve had the same problems with simple SocketConnections, the issue exists on both, simulator and 8900. Any ideas? This can´t be so complicated ....

 

TIA!

Please use plain text.
Developer
Posts: 1,474
Registered: 04-14-2009

Re: TCP connections suck ... any of them

[ Edited ]

Please post the detail message of the exception as well as the stack trace.

 

P.S. Try connecting your BlackBerry client to a known good HTTP server to confirm that the issue is not related to your server.

Message Edited by klyubin on 06-10-2009 07:44 PM
Please use plain text.
Developer
peter_strange
Posts: 14,614
Registered: 07-14-2008

Re: TCP connections suck ... any of them

How big is the file you are sending?

 

The BlackBerry should throw an Exception at some stage, which will give you some clues.  In your hang situations, what Exception do you see on the BlackBerry.

 

One thing that worries me in your Blackberry code is:

oGaugeField.setValue((int)net.rim.device.api.util.MathUtilities.round(100.0/vTotal*vRead));

 

This indicates that you are directly updating the GUI with the progress of your network activity, which suggests you are running on the Event Thread.  Are you starting a separate Thread to process your http connection? 

 

Please use plain text.
New Developer
maltic
Posts: 49
Registered: 09-25-2009

Re: TCP connections suck ... any of them

Hi,

 

thanks for the fast answer. The C# apps throws an InvalidOperationException saying that the stream cannot be closed until not all bytes have been written, in the try catch section I get the message that the app tries to access a non existing network connection. The BB gives java.io.IOException: TCP receive timed out.

 

I wrapped the gauge update into   synchronized(Application.getEventLock()) - no change.

 

The file as about 7MB.

 

Which stack trace do you want?

 

I tried an IIS7 with the same file - same result!

 

 

Please use plain text.
Developer
Aviator168
Posts: 694
Registered: 09-10-2009
My Carrier: Verizon

Re: TCP connections suck ... any of them

Direct tcp connection from my 9000 to a server can last as long as I want and trans/recv as much as I want either over 3G or wifi except that it is not as fast as I have hoped.
Please use plain text.
Developer
Posts: 1,474
Registered: 04-14-2009

Re: TCP connections suck ... any of them

[ Edited ]

As peter_strange has already pointed out, please make sure this BlackBerry code is running in thread that is not the event thread. I also suggest you read the Javadocs for the HttpConnection interface and then also try the example mentioned in the "Example using ContentConnection" subsection (basically, open a DataInputStream and read the full content-length in one big operation) to see whether it makes a difference.

 

P.S. I suspect the issue might be down to the now classic issue where requesting to read too much from an InputStream of a socket/http connection may block until the stream is closed/reset by peer. If that's the case, then using the DataInputStream.readFully with the correct length should work...

Message Edited by klyubin on 06-10-2009 08:26 PM
Please use plain text.
Developer
peter_strange
Posts: 14,614
Registered: 07-14-2008

Re: TCP connections suck ... any of them

Are there limits to the payload you can send with an http response?  7M seems a lot, but this is not an area of expertise. 

 

Aviator168 - are you using http connection to send/receive this data?

Please use plain text.
Developer
Aviator168
Posts: 694
Registered: 09-10-2009
My Carrier: Verizon

Re: TCP connections suck ... any of them

[ Edited ]

No. Just direct TCP   (socket//server:smileytongue:ort;deviceside=true). I was able to transmit and recv for many MBytes in a few hours until I kill it. There are two seperate threads. One for recv and one for send, and I keep counters (keep track of bytes send and recv) on the thread objects. I make a menu item action to peek into those counters. I was able to leave the app running for hours and end.

 

EDIT: The only thing I am struggling is to find a way to increase the speed. Too bad I only have access to one phone.

 

EDIT:smileyvery-happy:oesn't http connection go through the carrier's proxy? Wonder if that has anything to do with it.

Message Edited by Aviator168 on 10-06-2009 09:07 PM
Please use plain text.
New Developer
maltic
Posts: 49
Registered: 09-25-2009

Re: TCP connections suck ... any of them

Hi,

 

again thanks for the answers. I doubt that it would be possible to read the contents of the remote file completely because the filesizes can vary and do not have a limit, so there could be 100MB or more.

 

Aviator: could you send a code snippet of your app? HTTP traffic can you directly and by WIFI, too, not only through the carrier´s network.

 

There was also the notice that I shouldn´t put the download in the event thread. What does this mean? I have a main threat where I track the buttons and start a new thread from there which starts the download.

Please use plain text.
Developer
Posts: 1,474
Registered: 04-14-2009

Re: TCP connections suck ... any of them

[ Edited ]
Regarding threading, this is exactly what we meant: your network I/O code should run in non-UI threads. So, you seem to be OK on this front.
Message Edited by klyubin on 07-10-2009 11:10 AM
Please use plain text.