최근 출시된 안드로이드에서 TCP 소켓 통신을 하려다가 3가지 문제에 부딪혔다.


1. 소켓이 열리지 않는다.

2. 소켓은 열렸는데 죽는다.

3. 바이트 단위로 데이터를 보내고 싶은데 잘 모르겠다.




1. 소켓이 열리지 않는 것은, 참조한 샘플 소스가 대부분 옛날 소스이기 때문이다. 소켓을 생성할 때 쓰레드로 띄우지 않으면 소켓이 열리지 않는다.

//선언부

    private Socket socket;

    private BufferedReader networkReader;

    private BufferedWriter networkWriter;

    private DataOutputStream outStream;

    private String msg = "zxcf";    

    private String ip = "192.168.7.101"; // IP

    private int port = 1470; // PORT번호


    int tcp_flag = 0;

//OnCreate

        MainThread thread = new MainThread();

        thread.setDaemon(true);

        thread.start();


아래쪽에 붙일 것

    public void setSocket(String ip, int port) throws IOException {

        try {

        socket = new Socket(ip, port);

            networkWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));

            tcp_flag = 1;

            outStream = new DataOutputStream(this.socket.getOutputStream()); 

            //networkReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));

        } catch (IOException e) {

            System.out.println(e);

            e.printStackTrace();

        }

    }

    

    class MainThread extends Thread {

    public void run (){

    try{

    setSocket(ip, port);    

    } catch (IOException e1) {

    e1.printStackTrace();

    }

    }

    }




2. 보통 샘플들이 소켓을 열고 나서, 글자를 입력하고 버튼을 눌러야먄 동작한다. 그런데 만약 당신이 소켓을 열자마자 동시에 통신을 하려고 하면 앱이 뻗어버린다. (죽어버린다.) 한참 고민하다가 로그를 한줄마다 다 삽입해서 원인을 확인했다.


1번을 적용한 경우에 소켓은 쓰레드에서 열리고 onCreate는 별도로 진행하게 된다. 문제는 소켓이 열리기 전에 tcp 통신을 시도하려고 하면 죽게 된다. 그래서 소켓이 열린 후에 플래그를 바뀌고, 플래그에 따라 통신을 시도하면 된다.


if ( tcp_flag == 1) {

PrintWriter out = new PrintWriter(networkWriter, true);

byte headerbuf[] = new byte[16];

byte[] serialbuf = Build.SERIAL.getBytes();

headerbuf[0] = (byte)0xaa;

headerbuf[1] = (byte)0xaa;

headerbuf[2] = (byte)0xF;

headerbuf[3] = (byte)Build.SERIAL.length();

headerbuf[4] = serialbuf[0];

headerbuf[5] = serialbuf[1];

headerbuf[6] = serialbuf[2];

headerbuf[7] = serialbuf[3];

headerbuf[8] = serialbuf[4];

headerbuf[9] = serialbuf[5];

headerbuf[10] = serialbuf[6];

headerbuf[11] = serialbuf[7];

headerbuf[12] =   (byte) (Integer.parseInt(CurrentZone) - 10000);

headerbuf[13] =   (byte) (10006 - 10000);

headerbuf[14] = (byte)0xfa;

headerbuf[15] = (byte)0xfa;

 

// Send Header

try {

outStream.write(headerbuf);

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

try {

outStream.flush();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}


즉 플래그가 바뀐 상태에서 소켓 통신을 시도해야만 가능하다.


3. 대부분 TCP 통신 샘플 소스 코드는 println만 지원하므로 DataOutputStream을 이용하는 샘플을 찾아보면 쉽게 할 수 있다.

'업무 > 코딩' 카테고리의 다른 글

logback android 삽질 후기  (0) 2014.11.28

WRITTEN BY
가별이
내가 천사의 말 한다 해도

,