[Android] 네트워킹 1
네트워크를 이용해 서버에 데이터를 요청하고 응답받아 다른 사용자와도 소통해보자.
클라이언트는 서버에 데이터를 요청하고 서버는 그 요청에 대해 응답하는 형식의 2-tier 모델이 있다. 이 경우에 서버가 직접 데이터베이스를 다루고 만약 데이터베이스를 다루는 방식에 변화가 있으면 클라이언트에도 문제가 생긴다.
이 문제를 해결하기 위해 3-tier 모델이 도입됐다. 클라이언트와 서버가 소통하는 점에서는 2-tier 모델과 같지만, 서버를 응용 서버와 데이터 서버로 분리해 데이터를 관리하는 서버를 따로 구성하는 부분에서 차이가 있다. 이 외에도 서버를 두지 않고 단말끼리 서버와 클라이언트 역할을 하는 P2P모델도 있는데, 자세한 내용은 데이터베이스를 공부할 때 다루기로 하고 지금은 이 정도만 공부하자.
소켓을 사용하면 복잡한 네트워크 프로그램을 단순하게 추상화해서 사용할 수 있다.
소켓을 사용하는 프로그래밍은 TCP 연결과 UDP 연결으로 나누어 볼 수 있다. 대부분의 프로그래밍에서 TCP를 사용하므로 TCP 기반 소켓에 대해 알아보자.
서버와 클라이언트가 있을 때 클라이언트는 서버에 접근하기 위해 소켓이라는 개체를 만든다. 그리고 서버는 서버 소켓을 만들어 클라이언트와 연결한다. 이 두 소켓이 연결되고 통로가 생기면 Stream 객체를 사용해서 데이터를 보내거나 받을 수 있다. (자바의 입출력 파트 write 를 사용해서 서버가 클라이언트에게 데이터를 전달한다.)
이 때 데이터는 binary 형식으로 0 과 1 의 형태로 주고받는데, 이 덕분에 속도는 빠르지만 여기서 이 데이터가 문자열인지, 숫자인지에 대해서 약속이 있어야 한다. (HTTP를 이용한 통신에서는 텍스트를 주고받는다. )
정리하면, 소켓 연결 방식에서는 표준 자바의 소켓을 그대로 사용할 수 있고 서버 쪽에서는 서버 소켓을, 클라이언트에서는 소켓을 만들어서 둘을 연결한다.
네트워킹을 사용할 때는 쓰레드를 반드시 사용해야 한다.
메인 쓰레드는 자기가 할 일을 수행하게 하고, 쓰레드를 통해 네트워킹 작업을 수행하도록 한다.
쓰레드는 핸들러 없이 UI를 변경할 수 없다. 위의 작업 순서도와 같이 핸들러를 생성하고 핸들러의 post()메서드를 이용해 UI에 접근한다. (UI 업데이트를 위해 핸들러를 사용)
이제 소켓을 사용하는 예시를 살펴보자.
화면은 위와 같이 구성한다.
버튼을 눌렀을 때 프린트되는 작업은 핸들러가 수행한다.
전송 버튼을 눌렀을 때 의 코드이다.
쓰레드를 하나 만들고 실행했을 때 send() 메서드를 실행하도록 했다.
send() 메서드에 소켓을 생성하는 과정이 포함돼있다.
서버 시작 버튼을 눌렀을 때의 코드이다.
쓰레드를 하나 만들고 실행 시 startServer() 메서드를 실행한다.
이 메서드에 서버 소켓을 만드는 과정이 포함돼있다.
send 메서드이다.
클라이언트 쪽의 소켓을 만든다. 소켓을 만들 때는 그 서버가 실행되고 있는 IP주소를 알아야 하는데, 이 부분을 localhost로 현재 서버로 지정해 줬다.
소켓을 연결시킨 다음에 서버에 데이터를 보내려면 OutputStream을 만들어야 한다.
이 때 데이터는 String 타입인데, 편의상 ObjectOutputStream으로 지정했다.
서버로부터 응답을 받으려면 InputStream을 만들어야 한다.
startServer 메서드이다.
아까는 클라이언트 소켓이였고, 여기서는 서버 소켓을 만든다.
서버는 무한루프를 돌며 클라이언트의 응답을 기다린다. (server.accept() 메서드가 대기를 의미)
클라이언트에서 요청이 있으면 소켓 객체를 만들고 클라이언트의 정보를 얻어오고 클라이언트와 연결한다.
서버는 클라이언트가 전달하는 데이터를 받아서 from Server를 붙여서 다시 보내주는 역할을 한다.
클라이언트가 write한 데이터를 읽기 위해 readObject 메서드를 실행한다.
클라이언트가 보낸 데이터를 읽은 다음, 여기에 from Server를 붙여서 write를 수행한다.
즉, 클라이언트가 서버에게 요청할 때 write
서버가 클라이언트의 요청을 읽어올 때 read
서버가 클라이언트에게 응답을 보낼 때 write 를 사용한다.
자바 코드는 여기서 끝인데, 네트워킹을 사용하려면 한 가지 더 구현해 줄 게 있다.
AndroidManifest.xml 파일에 위의 코드를 추가해야 한다.
아까 잠시 봤었던 HTTP를 이용해 웹으로 요청하는 예제도 살펴보자.
웹 페이지는 텍스트로 되어 있다. 이전의 휴대전화 단말은 데이터의 송수신 속도가 느리고 비연결성이라(편지를 생각하자) 새로 연결을 만드는 데 시간이 많이 소모되는 HTTP를 거의 사용하지 않고 소켓을 통해 네트워킹을 진행했었는데, 최근 단말의 성능 및 무선 환경이 많이 개선돼서 HTTP 프로토콜을 이용한 웹의 사용이 원활해졌다. 지금은 HTTP 프로토콜을 사용하는 웹이 일반적이게 됐으니 자바에서 사용하던 HTTP 관련 클래스를 그대로 사용해 안드로이드에서 HTTP를 사용해 보자.
모든 웹 페이지들은 자신만의 주소(url)를 가지고 있다.
특정 주소를 가져오려면 URLConnection 클래스를 사용해 주소를 가져올 수 있다. (자바 참고)
웹으로 요청하는 예시를 통해 알아보자.
화면 구성은 위와 같이 돼있다.
요청하기 버튼을 누르면 쓰레드를 만들고 request 메서드를 실행시킨다.
여기서 urlStr 변수는 메인 쓰레드에서 만들었고, urlStr을 가져다 쓰는 쓰레드는 메인 쓰레드가 아니다.
쓰레드끼리는 전역변수를 공유하기 때문에 urlStr이 수정될 수 있는데, 이를 방지하기 위해 메인메서드에서 urlStr을 정의할 때 final 접근 제어자를 urlStr에 붙여서 사용한다.
url 객체를 만들고 형변환을 통해 url을 HttpURLConnection 형태로 받아온 후 받아온 conn 변수 통해서 HttpURLConnection 클래스의 메서드를 사용해서 요청을 처리한다.
서버가 응답하지 않을 경우를 생각해서 10초가 지나면 timeout 하도록 했다.
읽어온 url을 통해 안의 내용을 한 줄 단위로 읽어왔다.
역시 화면에 출력하는 동작은 핸들러를 사용해서 처리했다.
xml 파일에 인터넷 권한을 주고 모든 Http 주소에 접근할 수 있도록 한다.
'Mobile > Android' 카테고리의 다른 글
[Android] 채팅 어플 만들기 (2) | 2022.01.02 |
---|---|
[Android] 네트워킹 2 (0) | 2021.12.13 |
[Android] 내용 제공자 (Content Provider) (0) | 2021.11.29 |
[Android] 모바일 데이터베이스 (0) | 2021.11.21 |
[Android] 음악 재생 플레이어 만들기 (0) | 2021.11.21 |
댓글
이 글 공유하기
다른 글
-
[Android] 채팅 어플 만들기
[Android] 채팅 어플 만들기
2022.01.02 -
[Android] 네트워킹 2
[Android] 네트워킹 2
2021.12.13 -
[Android] 내용 제공자 (Content Provider)
[Android] 내용 제공자 (Content Provider)
2021.11.29 -
[Android] 모바일 데이터베이스
[Android] 모바일 데이터베이스
2021.11.21