안드로이드 소켓 서버 파일 수신

조회수 2489회

임베디드 보드에서 mp3파일이나 wav파일을 읽어서 tcp를 통해서 스마트폰으로 전송받는 앱을 만들고있습니다 c에서는 다음과 같이

struct filestate{ char state[5]; int size; char data[500] }; 512바이트로 구성되었구요 fread를 통해서 파일을 읽고 write함수를 통해서 전송을 했습니다

state의 경우 파일의 실제 데이터임을 알려주는 정보를 넣고 size는 지금 전송한 데이터의 사이즈를 어디까지 읽어야되는 알려주는 정보를 닮았고 실제 데이터는 500바이트 짜리 배열에 담았습니다

안드로이드에 파일 수신을 위한 스레드코드입니다

보내는 쪽에서는 분명히 데이터를 제대로 보내준거 같은데 받을때 뭔가 이상해서 state쪽 로그를 찍어봤는데 실제 파일의 정보임을 알려주는 state의 값인 Fbody의 값이 처음에 몇번정도만 찍히고 나머지는 제가 보내주지 않은 이상한 값이 찍히는데 값이 뒤죽 박죽으로 들어오는것도 가능한건가요? 이경우 어떻게 해결해야 할지 궁금합니다

class FReceiveThread extends Thread { boolean isLoop = true;

    public void setIsLoop(boolean isLoop)
    {
        this.isLoop = isLoop;
    }

    @Override
    public void run()
    {
        ServerSocket serverSocket = null;
        try
        {

            Log.i("SocketService", "Start Freceive");

            String state;
            int Fsize = 0;
            int Bsize = 0;
            int j = 0;
            serverSocket        = new ServerSocket(8005);
            Socket socket       = serverSocket.accept();
            //BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            DataInputStream in  = new DataInputStream(socket.getInputStream());
            FileOutputStream fos = null;
            byte[] dataBuff     = new byte[512];
            byte[] stateBuff    = new byte[5];
            byte[] sizeBuff     = new byte[4];
            byte[] BodyBuff     =new byte[500];

            while (isLoop)
            {

                Log.i("Freceive", "TopWhile");

                in.read(dataBuff,0,dataBuff.length);
                System.arraycopy(dataBuff,0,stateBuff,0,5);
                state           = new String(stateBuff);

                Log.i("Freceive", "state:" +state);

                if(state.equals("Finfo"))
                {
                    //Log.i("Freceive", "if(Finfo)" );

                    System.arraycopy(dataBuff,8,sizeBuff,0,4);

                    //Log.i("FreceiveSizeBuff", ""+sizeBuff[0]);
                    //Log.i("FreceiveSizeBuff", ""+sizeBuff[1]);
                    //Log.i("FreceiveSizeBuff", ""+sizeBuff[2]);
                    //Log.i("FreceiveSizeBuff", ""+sizeBuff[3]);

                    Fsize = ((sizeBuff[3]&0xff) << 24) | ((sizeBuff[2]&0xff) << 16) | ((sizeBuff[1]&0xff) << 8) | (sizeBuff[0]&0xff);
                     //int* psize = (intsizeBuff;
                     //Fsize=getInt(sizeBuff);

                    File StoreDir                   = new File(AppDirectory);

                    if( !StoreDir.exists() )
                    {
                        StoreDir.mkdirs();
                    }

                    Log.i("Freceive", ""+Integer.toString(Fsize));

                    file = new File(AppDirectory+"/"+messege);

                    fos = new FileOutputStream(file);

                }
                else if(state.equals("Fbody"))
                {
                    System.arraycopy(dataBuff,8,sizeBuff,0,4);

                    //Log.i("FreceiveSizeBuff", ""+sizeBuff[0]);
                    //Log.i("FreceiveSizeBuff", ""+sizeBuff[1]);
                    //Log.i("FreceiveSizeBuff", ""+sizeBuff[2]);
                    //Log.i("FreceiveSizeBuff", ""+sizeBuff[3]);

                    Bsize = ((sizeBuff[3]&0xff) << 24) | ((sizeBuff[2]&0xff) << 16) | ((sizeBuff[1]&0xff) << 8) | (sizeBuff[0]&0xff);
                    Log.i("Freceive", ""+Integer.toString(Bsize));
                    System.arraycopy(dataBuff,12,BodyBuff,0,500);
                    fos.write(BodyBuff,0,Bsize);
                    //fos.flush();
                    j +=Bsize;
                }
                else if(state.equals("Fend!"))
                {
                    Log.i("FileE","Fclose"+j);
                    j = 0;
                    //Log.i("FileE","Fclose"+j);
                    fos.close();
                }

            }


        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
}

1 답변

  • 도움이 되실진 모르겠으나 참고해보세요. 코드는 안보고 찾아갈수 있는 팁정도만 드릴게요.

    • C에서는 Struct padding 이라는 것이 있습니다. 임베디드OS쪽에서는 어떻게 패딩을 넣을지는 모르나 그냥 시원하게 아래 전처리 코드 쓰시고요. ( 패딩생각해서 하셨다면 512byte 잘 구성하긴 하셨습니다. )
    #pragma pack(1)
    
    • JAVA쪽에서 recv받을때 디버깅을 위해서 송신쪽에 한번만 데이터를 날리시고 520byte 정도 받아서 헥사코드로 출력해보시고 보낸 512byte만큼 똑같이 오는지 확인해보세요.

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)