https://swlock.blogspot.com/2018/04/usb-connection-to-pc-in-android.html
지난 글에 이어서 이번에는 해당 소스 분석입니다.
APK 측
전화기에서 Socket server를 생성합니다.아래 소스입니다. 30300 은 APK 내에서의 서버 Listen 소켓을 의미합니다.
이때 타임 아웃을 60초로 두었습니다. 필요에 따라 조정 하면 됩니다.
public static final int TIMEOUT=60;
server = new ServerSocket(30300); server.setSoTimeout(TIMEOUT * 1000); Log.d(TAG, "Waiting for connection.");
아래 구문에서 client의 접속이 들어오기 전까지 blocking 됩니다. 그래서 thread로 작성이 되었습니다.
//attempt to accept a connection client = server.accept();
이 connection은 한번만 하나의 장치만 연결하는 목적이므로 finally 구문에서 서버 소켓을 close 해줍니다. server.close()
} finally { //close the server socket try { if (server!=null) Log.d(TAG, "Closing server"); server.close(); } catch (IOException ec) { Log.e(TAG, "Cannot close server socket" + ec); } }
서버에 client 가 연결되자 마자 Globals.connected 가 true가 됩니다.
그리고 시작하자마자 tx thread를 만들어 줍니다.
해당 코드는 Globals.connected true일때만 동작하게 됩니다.
지속적으로 현재시간을 socket에 write를 합니다.
while(true){ while(Globals.connected) { Log.d(TAG, "writing things"); Globals.socketOut.write("Time: " + System.currentTimeMillis() + "\n"); Globals.socketOut.flush();
UI 메세지 전달은 handler를 통해서 진행합니다. thread안에서 화면에 문구를 업데이트 하는 부분은 어렵기 때문에 handler.post에 showConnectionStatus 를 호출하면 Handler가 this.mHandler = new Handler(); 를 Creat시 생성해두었기 때문에 ui thread에서 실행이 됩니다.
connectionStatus="Connection was successful!"; mHandler.post(showConnectionStatus);
=> 아래 코드가 실행 됩니다.
private Runnable showConnectionStatus = new Runnable() { public void run() { Toast.makeText(MainActivity.this, connectionStatus, Toast.LENGTH_SHORT).show(); } };
ADB에 의해서 port forward로 PC 10300 포트가 단말 30300 번 과 연결이 되어 있습니다.
따라서 10300으로 접속을 하게 되면 단말 30300으로 연결이 되게 됩니다.
adb forward tcp:10300 tcp:30300
PC 프로그램 측
localhost는 PC자신을 의미하고 10300 포트로 접속하기위해 소켓을 만듭니다.라인단위씩 주고 받기 위해서 stream에 연결하였습니다.
socket = new Socket("localhost", 10300); out = new PrintWriter(socket.getOutputStream(), true); //in = new BufferedReader(new InputStreamReader(socket.getInputStream())); sc = new Scanner(socket.getInputStream());
아래코드는 종료될때 소켓을 닫아주기 위해서 존재합니다.
// add a shutdown hook to close the socket if system crashes or exists unexpectedly Thread closeSocketOnShutdown = new Thread() { public void run() { try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } }; Runtime.getRuntime().addShutdownHook(closeSocketOnShutdown);
Socket scanner에 데이터가 있으면 화면에 출력하는 문장입니다.
while(t.sc.hasNext()) { System.out.println(System.currentTimeMillis() + " / " + t.sc.nextLine()); }
덕분에 상당부분 고민하던 부분이 대부분 해결되었습니다. 감사합니다.!!
답글삭제