Почему приложение работает во время отладки, но не работает при запуске? - PullRequest
2 голосов
/ 20 июня 2011

У меня есть клиент в Android и сервер в C #, они общаются через сокет. У меня есть эта проблема - если я запускаю свое клиентское приложение в режиме отладки и устанавливаю точку останова в нужном месте - она ​​работает отлично, но без нее - нет. Клиент отправляет адрес изображения на сервер, сервер делает его миниатюру, преобразует его в байт [] и отправляет обратно. Клиент получает байт [], преобразует его обратно в изображение и показывает его. Я также обнаружил, что когда он не получает правильный байт [], его размер равен 2896, а иногда 1448, независимо от того, какой был исходный размер отправленного массива.

Вот клиент:

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(); 
    }       
}

Вот сервер:

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();
}

}

Ответы [ 2 ]

5 голосов
/ 20 июня 2011

Метод read (byte []) в InputStream считывает столько байтов, сколько в настоящее время доступно.Это не обязательно означает, что больше байтов не будет доступно позже.Поэтому вам нужно сделать что-то вроде

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

  // else
  add read buffer to image array
}

extract image from image array

, где «массив изображений» - это некоторый байтовый массив, в который вы продолжаете добавлять буфер чтения, пока не достигнете конца потока.

Причина, по которой ваш код работает с точкой останова, заключается в том, что к тому времени, когда вы проходите через отладчик, весь поток становится доступным, тогда как при отсутствии отладки весь поток еще не доступен, когда вы выполняете чтение.*

1 голос
/ 20 июня 2011

Разница, вероятно, связана с тем, что в отладчике вы можете замедлить и остановить приложение - это дает время серверу ответить на ваш вызов. Похоже, вы не используете асинхронные методы для вызова сокета подключения (ну, я все равно не вижу никаких доказательств этого в вашем коде).
Чтобы это исправить, попробуйте расширить объект AsyncTask примеры здесь
РЕДАКТИРОВАТЬ: @Carsten, вероятно, имеет правильное решение, но вы все равно должны использовать AsyncTask, если вы еще не сделали.

...