마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

안드로이드스튜디오 소켓통신 수신관련 질문입니다

0 추천
byte[] buf = new byte[1024];

                int readBytes=0;

                try {
                    FileOutputStream output = openFileOutput(filename, Context.MODE_PRIVATE);
                    // /data/data/com.example.software.a20190411/files/ 파일경로
                    while ((readBytes = socket.getInputStream().read(buf)) != -1) {
                        output.write(buf,0,readBytes);
                        Log.d(String.valueOf(MainActivity.this),"-----------"+readBytes+"-----------");
                    }
                    output.close();
                    Log.d(String.valueOf(MainActivity.this),"############"+readBytes+"############");
                } catch (FileNotFoundException e){} catch (IOException e){}
            }
 
디버그기록보면 -------readBytes-------- 까지는 출력되는데 
그이후로 while문에서 나오질 못합니다 방법아시는분? 

 

안드너무어려워 (140 포인트) 님이 2019년 4월 15일 질문

2개의 답변

0 추천
-1 이 아니라 null 로 해보겠어요?
익명사용자 님이 2019년 4월 15일 답변
int형 이라서 null로는 비교할수 없다고 빨간줄 생깁니다
>0 으로도 해봤는데 while을 나가질 못하네요 후
NULL은 되네요 그래도 해결은 안됩니다....
0 추천
일반적인 HTTP 통신 구조로 구현 하신 듯 한데.

socket 통신은 동작이  달라 이 방식으로 구현 하시면 안됩니다.

blocking socket 의  read 경우  데이터가 들어어가나 타임아웃 될 때 까지 대기하는데,

서버에서 한번 socket 에 데이터를 write 한 이후 더이상 데이터를 write 하지 않아서,

단말에서 다시 read 부를 때 blocking 되어 멈췄을 듯 합니다.

 

메세지 뒤에 종료 정보를 둬서 그 이후로는 read를 부르지 않거나,

서버에서 처음에 사이즈 보내고, 이후 그 사이즈만큼의 데이터를 보내는 방식으로 구현하고,

단말에서 사이즈를 구한 후 그 사이즈 만큼 read하게 구현 하셔야 합니다.
익명사용자 님이 2019년 4월 15일 답변
2019년 4월 15일 수정
while문 안쪽에 if를 둬서 readBytes를 로그캣으로 보며 조건을 줬봤습니다만 if문에 걸려도 while에서 빠져나오질 않아요
if 문 거셨던 코드좀 보여주세요. 단순 break 문이라면 안 빠져 나올리가 없을텐데.. 다른 이슈가 있을 것으로 생각됩니다.
byte[] buf = new byte[1024];

                int readBytes;

                try {
                    InputStream is=socket.getInputStream();

                    FileOutputStream output = openFileOutput(filename, Context.MODE_PRIVATE);

                    // /data/data/com.example.software.a20190411/files/ 파일경로

                     while ((readBytes =is.read(buf)) > 0) {

                       output.write(buf,0,readBytes);
                       if(readBytes < 10) break;

                       Log.d(String.valueOf(MainActivity.this),"-----------"+readBytes+"-----------");
                   }
                    Log.d(String.valueOf(MainActivity.this),"-----------SUCCESS-----------");
                    output.close();
이건 로그캣입니다
2019-04-15 18:50:58.407 6633-6666/com.example.software.a20190411 D/com.example.software.a20190411.MainActivity@5da23ec: -----------1024-----------
2019-04-15 18:50:58.407 6633-6666/com.example.software.a20190411 I/chatty: uid=10085(com.example.software.a20190411) Thread-5 identical 6 lines
2019-04-15 18:50:58.408 6633-6666/com.example.software.a20190411 D/com.example.software.a20190411.MainActivity@5da23ec: -----------1024-----------
2019-04-15 18:50:58.408 6633-6666/com.example.software.a20190411 D/com.example.software.a20190411.MainActivity@5da23ec: -----------448-----------
2019-04-15 18:50:58.409 6633-6666/com.example.software.a20190411 D/com.example.software.a20190411.MainActivity@5da23ec: -----------1024-----------
2019-04-15 18:50:58.484 6633-6666/com.example.software.a20190411 I/chatty: uid=10085(com.example.software.a20190411) Thread-5 identical 180 lines
2019-04-15 18:50:58.484 6633-6666/com.example.software.a20190411 D/com.example.software.a20190411.MainActivity@5da23ec: -----------1024-----------
2019-04-15 18:50:58.484 6633-6666/com.example.software.a20190411 D/com.example.software.a20190411.MainActivity@5da23ec: -----------465-----------
2019-04-15 18:50:58.671 2690-2690/? I/Finsky: [2] com.google.android.finsky.scheduler.JobSchedulerEngine$PhoneskyJobSchedulerJobService.onStartJob(3): onJobSchedulerWakeup with jobId 9000
2019-04-15 18:50:58.674 2690-2690/? I/Finsky: [2] paw.a(21): Scheduling fallback job with id: 9034, and delay: 43200000 ms
2019-04-15 18:50:58.676 2690-2690/? I/Finsky: [2] paw.a(5): Scheduling fallback in 64799999 (absolute: 92841037)
2019-04-15 18:50:58.730 2690-2690/? I/Finsky: [2] pbe.handleMessage(10): DeviceState: DeviceState{currentTime=1555321858726, isCharging=true, isIdle=false, netAny=true, netNotRoaming=true, netUnmetered=true}
2019-04-15 18:50:58.732 2690-6590/? I/Finsky: [683] pck.b(7): Jobs in database: 1-1337 12-1 26-1414141414
2019-04-15 18:50:58.734 2690-2690/? I/Finsky: [2] pax.a(45): Running job: 12-1
2019-04-15 18:50:58.738 2690-2690/? I/Finsky: [2] com.google.android.finsky.contentsync.ContentSyncJob.a(23): ContentSyncJob started
2019-04-15 18:50:58.738 2690-2690/? I/Finsky: [2] pbe.handleMessage(81): RunningQueue size: 1, PendingQueue size: 0
2019-04-15 18:50:58.739 2690-2690/? I/Finsky: [2] pbe.handleMessage(90): Running queue: 12-1
2019-04-15 18:50:58.739 2690-2809/? I/Finsky: [130] dfe.a(5): Completed 0 account content syncs with 0 successful.
2019-04-15 18:50:58.740 2690-2690/? I/Finsky: [2] com.google.android.finsky.contentsync.ContentSyncJob.a(21): Installation state replication succeeded.
2019-04-15 18:50:58.740 2690-2690/? I/Finsky: [2] pcd.a(11): jobFinished: 12-1. TimeElapsed: 4ms
2019-04-15 18:50:58.741 2690-2690/? I/Finsky: [2] pax.a(10): Job 12-1 finished
2019-04-15 18:50:58.741 2690-2690/? I/Finsky: [2] pbe.handleMessage(81): RunningQueue size: 0, PendingQueue size: 0
2019-04-15 18:50:58.741 2690-2690/? I/Finsky: [2] pbe.handleMessage(27): Executor finished
2019-04-15 18:50:58.783 2690-2690/? I/Finsky: [2] pck.b(7): Jobs in database: 1-1337 26-1414141414
2019-04-15 18:50:58.783 2690-2690/? I/Finsky: [2] pad.a(66): ConstraintMapping: 1-1337,  -> L: 2019493ms, D: 45219493ms, C: false, I: false, N: NET_ANY
2019-04-15 18:50:58.783 2690-2690/? I/Finsky: [2] pad.a(66): ConstraintMapping: 26-1414141414,  -> L: 27708255ms, D: 28608255ms, C: false, I: false, N: NET_NONE
2019-04-15 18:50:58.784 2690-2690/? I/Finsky: [2] com.google.android.finsky.scheduler.JobSchedulerEngine.a(42): Cancelling existing job with id: 9001
2019-04-15 18:50:58.787 2690-2690/? I/Finsky: [2] com.google.android.finsky.scheduler.JobSchedulerEngine.a(4): Scheduling job Id: 9002, L: 2019493, D: 45219493, C: false, I: false, N: 1
2019-04-15 18:50:58.788 2690-2690/? I/Finsky: [2] com.google.android.finsky.scheduler.JobSchedulerEngine.a(4): Scheduling job Id: 9003, L: 27708255, D: 28608255, C: false, I: false, N: 0
2019-04-15 18:51:00.025 1712-1896/? D/EGL_emulation: eglMakeCurrent: 0x9383f440: ver 3 0 (tinfo 0x93846450)
분명히 readBytes가 적어지면 while문이 돌수없고 빠져나와야하고 아니라면 Log가 계속 나와야 하는건데 모르겠습니다 ㅠㅠ
readBytes 가 10보다 적었는데 SUCCESS 가 안나오고 멈췄다는 말씀이신가요?
그게 아니라면 다시 read 하면서 멈춘듯 합니다.
10 보다 적었는데. 멈췄다면, 디버깅 물려 한줄씩 확인 해보세요.
SUCCESS 가 안나오고 멈췄습니다  read하면서 멈추면 이미지가 전송이 제대로 되나요?? 이미지는 정상적으로 받아집니다.
logcat에 찍힌 값이 10보다 적은적이 없으니 break가 호출되지 않아 계속  read를 부를 듯 한데요. 465 받았을 때,  실제  데이터는 서버에서 다 받았으나, break 조건문을 만족하지 않아서 read를 다시 불렀고 blocking 된걸로 생각됩니다.
조건을 어떤걸 걸면 좋을지 모르겠습니다 하 ... 아니면 서버에서 보낼때 끝 맺음 메시지를 전송하는 방법으로 가야겠습니다
서버에서  처음에 4byte(int) 혹은 8byte(long) 형식의 전송할 사이즈 정보를 보내고, 그 사이즈 만큼 데이터를 보내는 방식으로 구현하고, 받는데서 사이즈 정보를 받아 그 사이즈 만큼 read를 하게 구현하게 제일 좋을듯 하나,

서버서 전송을 다 한 후 서버의 socket을 close 시켜 read 함수가 반환되게 하는것도 가능은 합니다.

 종료 문자를 보내는 방식도 가능은 합니다만 1byte씩 받아, 종료를 다 받았는지 계속 확인해야 해서, 퍼포먼스 측면에서 좋지 않는듯 합니다.
...