안드로이드, 자바간 소켓 서버통신 중에 문제가 생겼습니다.

조회수 856회

클라이언트 쪽 코드입니다.

public class Bring extends AppCompatActivity {

BufferedReader in;
Button button;
TextView textView;
private BufferedWriter out;
private Socket sock;
private String ip = "192.168.0.2";
private int port = 15001;
String externalDir;
String dirname="/bringdata";
static final String BRING_SGINAL="9,";

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_bring);

    TextView textView = findViewById(R.id.textView);
    Button button = findViewById(R.id.button3);

    requestPermissions(new String[] {Manifest.permission.WRITE_EXTERNAL_STORAGE}, MODE_PRIVATE);
    externalDir= Environment.getExternalStorageDirectory().getAbsolutePath();

    File saveFile = new File(externalDir + dirname);

    if (!saveFile.exists()) {
        saveFile.mkdir();
    }

    startthread.start();
}

protected void Return(View v){
    finish();
}

Thread startthread = new Thread() {
    public void run() {

        try {
            sock = new Socket(ip, port);

            in = new BufferedReader(new InputStreamReader(sock.getInputStream()));
            //송신부
            bringthread.start();
            bringthread.join();


            //수신부
            //in = new BufferedReader(new InputStreamReader(sock.getInputStream()));
            String str = in.readLine();
            BufferedInputStream up = new BufferedInputStream(sock.getInputStream());
            File f = new File(externalDir+ dirname +"/"+ str);
            FileOutputStream out = new FileOutputStream(f);
            BufferedOutputStream outFile = new BufferedOutputStream(out);

            int buf;

            while ((buf = up.read())!=-1) {
                outFile.write(buf);
                System.out.println(buf);
            }

            outFile.flush();
            outFile.close();
            out.close();
            in.close();
            up.close();

            runOnUiThread(new Runnable() {
                public void run() {
                    Toast.makeText(getApplicationContext(), "수신에 성공하였습니다.", Toast.LENGTH_SHORT).show();
                }
            });

        } catch (Exception e) {
            e.printStackTrace();
            runOnUiThread(new Runnable() {
                public void run() {
                    Toast.makeText(getApplicationContext(), "수신에 실패하였습니다.", Toast.LENGTH_SHORT).show();
                }
            });
        }
    }
};

Thread bringthread = new Thread() {
    public void run() {
        try {
            out = new BufferedWriter(new OutputStreamWriter(sock.getOutputStream()));

            PrintWriter print = new PrintWriter(out, true);

            print.println(BRING_SGINAL);
            print.flush();

        }catch (Exception e) {
            e.printStackTrace();
            runOnUiThread(new Runnable() {
                public void run() {
                    Toast.makeText(getApplicationContext(), "송신에 실패하였습니다.", Toast.LENGTH_SHORT).show();
                }
            });
        }
    }
};
}

서버쪽 코드입니다.

public class Server{
final static boolean LOG_ENABLE = true;
public static final int PORT = 15001;

public static void main(String[] args){

    Socket socket = null;
    BufferedReader in=null;

    BufferedWriter out=null;
    String[] f_array = new String[10];
    Random random = new Random();
    String B_file = null;
    int R_num = 0;

    for(int i=0; i<10; i++){
        f_array[i]=null;
    }
    //송신부
    try{
        ServerSocket serversocket = new ServerSocket(PORT);

        while(true){
            socket = serversocket.accept();
            log("클라이언트 연결되었음");
            try{
                in = new BufferedReader(new InputStreamReader(socket.getInputStream()));

                String str = in.readLine();

                int signal = Integer.parseInt(str.substring(0,1));

                if(signal == 9){

                    log("송신 요청");
                    String path="C:/inputdata";

                    File dirFile=new File(path);
                    File []fileList=dirFile.listFiles();
                    char k = 0;
                    for(File tempFile : fileList) {
                        if(tempFile.isFile()) {
                            String tempFileName=tempFile.getName();
                            if(k<10){
                                f_array[k]=tempFileName;
                                k++;
                            }
                            //log("FileName = "+tempFileName);
                        }
                    }

                    R_num = random.nextInt(5);
                    B_file = f_array[R_num];

                    while(B_file == null){
                        R_num = random.nextInt(5);
                        B_file = f_array[R_num];
                    }

                    log("송신할 파일 : "+ B_file);

                    out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
                    PrintWriter print = new PrintWriter(out, true);
                    print.println(B_file);
                    print.flush();

                    File file = new File( "C:/inputdata",B_file);
                    BufferedInputStream dis = new BufferedInputStream(new FileInputStream(file));
                    BufferedOutputStream toclient = new BufferedOutputStream(socket.getOutputStream());

                    int buf;

                    while ((buf = dis.read()) !=-1) {
                        toclient.write(buf);
                        log(Integer.toString(buf));
                    }

                    toclient.flush();
                    toclient.close();
                    dis.close();
                    socket.close();

                    log(file.length()+"byte, 송신 완료");

                }
                //수신부
                else{
                    log("수신요청");
                    String name = str.substring(2);
                    log("수신중인 파일 이름 : "+name);

                    BufferedInputStream up = new BufferedInputStream(socket.getInputStream());
                    File f = new File("C:/inputdata/"+name+".txt"); 
                    FileOutputStream fout = new FileOutputStream(f);
                    BufferedOutputStream outFile = new BufferedOutputStream(fout);

                    int buf=0;

                    while ((buf = up.read())!=-1) { //보낸것을 딱맞게 받아 write 합니다.
                        outFile.write(buf);
                    }

                    outFile.flush();
                    outFile.close();
                    fout.close();
                    in.close();
                    up.close();

                    log(name+" : 수신완료");
                }

            }catch(Exception e){
                log("서버에러");
                e.printStackTrace();
            }
        }
    }catch(Exception e){
        e.printStackTrace();
    }   
}

private static void log(String log){
    if(LOG_ENABLE){
        System.out.println(log);
    }
}

}

이렇게 짜놓았는데

이걸 클라이언트(안드로이드)->서버(자바)로 파일을 보낼때는 줄바꿈이 없어지는 문제가 있지만 정상작동합니다.

그런데 서버(자바)->클라이언트(안드로이드)로 보낼때에는 파일이 클라이언트(안드로이드)쪽에 만들어지긴 하지만 0byte짜리 빈파일이 만들어지고 내용이 없습니다. 서버에서 보낼때 buf 내용을 로그로 보면 확실히 보내는데 클라이언트에서 받을때 buf 내용을 로그로 보면 한번도 받지 못하고 while문을 한번도 안돌고 빠져나갑니다. 아마 클라이언트에서 파일 내용 자체를 못 받는거 같습니다 ㅠ

이게 왜 이러는지 모르겠습니다 도와주세요ㅠ

  • (•́ ✖ •̀)
    알 수 없는 사용자
  • 안드로이드의 문제인지 코드상의 문제인지 확인부터 해야 합니다. 일단 pc에서 서버/클라이언트 테스트를 해보세요. 그후 결과를 올려주세요. 정영훈 2019.6.2 00:01
  • 지금 안드로이드는 정상적으로 작동 하는거 같아요. 문제가 서버에서는 해당 파일 내용을 제대로 보내는데 정작 클라이언트 받을때 outFile.write(buf) 뒤에 system.out.println(buf)를 추가해서 로그로 보면 while문을 1번도 돌지 않고 빠져나가더라구요. 서버에서는 보냈는데 클라이언트에서는 해당 파일 내용을 못 받는거 같아요. 그리고 어쩌다 한번은 파일이 제대로 생성 됬었습니다. 어떻게 된 건지도 다시 재현도 못했지만요 ㅠ 알 수 없는 사용자 2019.6.5 14:03
  • 아 그리고 저 서버와 클라이언트 코드 앞에 다른 코드가 좀 있긴한데 저 문제가 있는 부분과는 큰 관계는 없습니다. 그저 클라이언트가 서버에 송신요청을 보낸다던가 서버에서 송신요청을 받아서 보낼 파일을 선택하는 코드 정도입니다. 알 수 없는 사용자 2019.6.5 15:34
  • 생각을 해보세요...일단 일부만 제공된 소스가지고는 디버깅을 해볼 수 없습니다. 즉 일부만 제공된 소스만 가지고는 제3자가 원인찾기가 어렵다는 뜻 입니다. 그러니 누구든지 테스트 할 수 있도록 최소한의 코드로 오류 재현을 해야 합니다. 그리고 그 코드를 공개해주세요. 정영훈 2019.6.5 18:24
  • 문제가 있는 클라언트쪽 코드 전체와 서버쪽 코드 전체를 올렸습니다. 메인 인텐트에서 버튼을 누르면 해당 코드 액티비티로 넘어가게 만들어서 저게 메인 액티비티는 아니긴 한데 메인 액티비티는 진짜 아무것도 없이 버튼만 있고 넘겨주는 인텐트내에 인자도 없습니다. 아 메인 액티비티에서 외장메모리 사용 허용 해줬고 매니페스트에도 써놨습니다. 어쩔때는 제대로 보내지고 어쩔떄는 0byte로 받고 원인을 모르겠네요 알 수 없는 사용자 2019.6.6 13:33
  • 클라이언트도 안드로이드(달빅) 말고 오라클 jvm용으로 올려주세요.(현재 안드로이드 개발 환경 없습니다.) 딱 오류가 재현될 최소한의 코드만 올리세요. 정영훈 2019.6.6 18:11

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

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

(ಠ_ಠ)
(ಠ‿ಠ)