Why an application works during debugging but doesn't work on run?
Asked Answered
R

2

5

I have a client in Android and server in C#, they communicate through socket. I have this problem - if I run my client app in debug mode and place a breakpoint in right place - it works perfectly, but without it it doesn't. Client sends adress of an image to server, server makes a thumbnail of it, converts it to byte[] and sends it back. Client gets the byte[], converts it back into image and shows it. I've also found out that when it doesn't get the right byte[] its size is 2896 and sometimes 1448, no matter what the original size of the array sent was.

Here's the client:

private void connectSocket(String a){ 

    try { 
        InetAddress serverAddr = InetAddress.getByName("192.168.1.2"); 
        Socket socket = new Socket(serverAddr, 4444); 
        String message = a;
        flag = 0;
        if(a.indexOf(".jpg")>0){
            flag = 1;
        }

        ListItems.clear();
        if(!a.equalsIgnoreCase("get_drives"))){
                    //.....
        }
        if(!ListItems.isEmpty()){               
            if(ListItems.get(0).matches("^[A-Z]{1}:$")){
                ListItems.set(0, ListItems.get(0)+"\\");
            }
        }
        PrintWriter out = null;
        BufferedReader in = null;
        InputStream is = null;          
        try { 
            out = new PrintWriter( new BufferedWriter( new OutputStreamWriter(socket.getOutputStream())),true); 
            in = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
            is = socket.getInputStream();
            out.println(message);

            String text = "";
            String finalText = "";
            if(flag!=1){
                while ((text = in.readLine()) != null) {
                    finalText += URLDecoder.decode(text, "UTF-8");
                    }
                String[] result = finalText.split("#");
                for(int i = 0; i<result.length; i++)
                    ListItems.add(result[i]);
                }
            if(flag ==1){                   

                    byte[] buffer = new byte[9999];
                 //placing breakpoint at the next line or before it makes it work fine                     
                    int size = is.read(buffer);
                //but placing a breakpoint at the line below doesn't make it work
                //it starts getting another byte array 
                    byte[] bufffer2 = new byte[size];
                    for(int g = 0; g<size;g++){
                        bufffer2[g] = buffer[g];
                    }
                    //is.read(bufffer2);
                    //int read = is.read(buffer);

                image = (ImageView)findViewById(R.id.imageView1);
                //while ((text = in.readLine()) != null) {
                //  byte[] b = in.readLine().getBytes();
                    Bitmap bmp=BitmapFactory.decodeByteArray(bufffer2,0,bufffer2.length);                       
                    image.setImageBitmap(bmp);
                //}
            }
            adapter.notifyDataSetChanged(); 

        } catch(Exception e) { 
            Log.e("TCP", "S: Error", e); 
        } finally { 
            socket.close(); 
        } 

    } catch (UnknownHostException e) { 
        Log.e("TCP", "C: UnknownHostException", e); 
        e.printStackTrace(); 
    } catch (IOException e) {  
        Log.e("TCP", "C: IOException", e); 
        e.printStackTrace(); 
    }       
}

Here's the server:

public class serv {
public static void Main() {
try {
    IPAddress ipAd = IPAddress.Parse("192.168.1.2");
    TcpListener myList=new TcpListener(ipAd,4444);

   m:      
    myList.Start();

    Socket s=myList.AcceptSocket();

    byte[] b=new byte[100];
    int k=s.Receive(b);

    char cc = ' ';
    string test = null;
    Console.WriteLine("Recieved...");
    for (int i = 0; i < k-1; i++)
    {
        Console.Write(Convert.ToChar(b[i]));
        cc = Convert.ToChar(b[i]);
        test += cc.ToString();
    }

    string[] response = null;
    ASCIIEncoding asen = new ASCIIEncoding();
    switch (test)
    {
        default:
            MyExplorer(test, s);
            break;

    }

    s.Close();
    myList.Stop();
    goto m;

}
catch (Exception e) {
    Console.WriteLine("Error..... " + e.StackTrace);        
}    
}

public static void MyExplorer(string r, Socket s){
    Image imgThumb = null;
    if (r.Contains(".jpg"))
    {
        Image image = null;
        image = Image.FromFile(r);
        // Check if image exists
        if (image != null)
        {
            imgThumb = image.GetThumbnailImage(100, 100, null, new IntPtr());
            s.Send(imageToByteArray(imgThumb));
            byte[] b = imageToByteArray(imgThumb);
        }
        return;
    }

}

public static byte[] imageToByteArray(System.Drawing.Image imageIn)
{
    MemoryStream ms = new MemoryStream();
    imageIn.Save(ms, System.Drawing.Imaging.ImageFormat.Gif);
    return ms.ToArray();
}

}
Russon answered 19/6, 2011 at 23:24 Comment(0)
S
5

The read(byte []) method in InputStream reads as many bytes as currently available. It does not necessarily mean that there won't be more bytes available later. So you need to do something like

while(true) {
  int s  = is.read(buffer);
  if(s == -1) break;

  // else
  add read buffer to image array
}

extract image from image array

where "image array" is some byte array where you keep adding the read buffer until you reach then end of the stream.

The reason your code works with the breakpoint is that by the time you go through the debugger the whole stream is available, while in non-debug the whole stream is not yet available when you do the read.

Sibilla answered 20/6, 2011 at 0:33 Comment(0)
K
2

The difference is likely due to the fact that on the debugger, you are able to slow and stop the application - this gives time for the server to respond to your call. It looks like you are not using any asynchronous methods to call connect socket (well, I can't see any evidence of this from your code anyway).
To fix this, you should try extending the AsyncTask object examples here
EDIT: @Carsten probably has the correct solution, but you should STILL use an AsyncTask if you are not already.

Kalisz answered 20/6, 2011 at 0:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.