이론공부/관련서적

안드로이드 네트워크 통신에 대하여

chobyeonggyu03 2024. 7. 17. 18:54
반응형

이번에는 현재 진행 중인 공모전에서 React Native언어에서 axios 라이브러리를 활용해 서버와 통신 중이었는데 JSON 파일만을 통신할 때는 문제없이 통신되었지만 이미지를 file의 형태로 보내기 위해 코드를 수정하는 과정에서 막히게 되어 관련 서적을 찾아보다, 직접적으로 도움받을 수 있는 axios관련 서적은 현재까지 찾지 못하여 안드로이드 네트워크와 관련된 서적을 건대 도서관에서 찾게 되었고, 해당 책을 접하게 되어 책에 나와있는 안드로이드 네트워크와 관련된 내용들을 블로그에 정리해 둔다면 이후 axios관련 정보글들을 접할 때 유용할 것 같아 이 글을 작성하게 되었다.

 

그럼 본격적으로 안드로이드 네트워크 통신에 대해 알아보도록 하겠다.

 

 

 

먼저 안드로이드 앱에서 데이터를 관리하는 방법에는 네트워크, 데이터베이스, preference 이렇게 총 3가지가 있는데, 네트워크를 활용하는 방법은 데이터를 로컬 디바이스에 저장하는 대신, 원격 서버에 저장하고 필요 서버와 네트워크 프로토콜을 통해 통신하며 데이터가 필요할 때마다 데이터를 조회하거나 업데이트하는 형식의 방법이다. 다음으로 데이터베이스를 활용하는 방법은 주로 안드로이드 디바이스 내에 내장되어 있는 SQLite 등의 데이터 베이스를 활용해 데이터를 관리하며 preference 방법은 주요 데이터를 관리하는 데에 쓰이기보다  사용자의 설정 값을 저장하는 데 주로 사용되며, SharedPreferences API를 통해 간단한 Key - Value의 형태로 데이터를 관리하는 방법이다.

 

이번 블로그에서는 3가지 안드로이드 데이터관리 방법들 중 '네트워크 통신'에 대해서 자세히 다뤄보도록 하겠다.

 

 

 

안드로이드 네트워크 통신

 

안드로이드에서 네트워크를 통해 데이터를 가져오는 방법에는 크게 2가지 방법이 있는데 하나는 HTTP 통신이고, 다른 하나는 소켓통신이다.

 

HTTP 통신은 대부분의 앱에서 사용하고 있는 통신 형태로서, 클라이언트 측에서 요청이 있을 때만 서버에서 해당 페이지의 정보를 전송하는 형태의 네트워크 통신이다. HTTP 통신은 요청이 없다면 정보를 전송해주지 않으므로 지속적으로 연결이 유지되는 구조는 아니기에 '비연결지향형 통신'에 속하며, 클라이언트 측에서 요청을 했을 때만 정보를 보낼 수 있는 '단방향 통신'에 해당한다. 이러한 특징 때문에 HTTP 통신은 클라이언트 측에서 대용량 컨텐츠를 다운받아야 하거나 실시간으로 빠르게 정보를 공유해야 하는 서비스를 제공하지 않을 때 많이 사용하게 되는 통신 방법이다.

 

반면, 소켓통신은 사전에 서버와 클라이언트 측에서 연결하기 위한 세팅을 모두 마쳐야 하지만 연결이 되기 시작하면, 둘 중 어느 한쪽에서 접속을 해제하지 않는 한 지속적으로 연결이 유지되는 구조이기에 '연결지향형 통신'에 속하며, 서버와 클라이언트 측이 모두 양쪽에서 데이터를 요청할 수 있기에 '쌍방향 통신'에 해당한다. 소켓통신은 이러한 특징들 때문에 실시간으로 빠르게 제공해야 하는 게임이나, 채팅, 온라인게임등에 많이 이용되는 통신 방법이다.

 

추가적으로 HTTP와 소켓통신에 대해 정리해 보자면, HTTP 통신은 인터넷에서 데이터를 주고받기 위한 서버/클라이언트 모델의 프로토콜이고, 소켓통신은 네트워크에서 서버와 클라이언트 두 개의 프로그램이 특정 포트를 통해 양방향 통신이 가능하도록 만들어주는 소프트웨어 장치이다.

 

(참고로 소켓통신은 그 안에서 신뢰성이 높은 TCP 프로토콜과 신뢰성이 낮은 UDP 프로토콜로도 나눠지는데 TCP소켓통신은 데이터 손실을 잡아주기 위해 데이터의 순서를 재정렬하거나 데이터를 재조합하는 기능이 있지만. UDP는 데이터 손실에 관여하지 않고 단순히 데이터를 던져주기만을 수행한다.)

 

 

 

 

안드로이드 네트워크 통신의 2가지 방법에 대해 위에서 가볍게 정리해 보았는데, 본격적으로 네트워크에 연결하는 방법에 대해 정리해 보기에 앞서 안드로이드 기기에서 네트워크에 연결 전에 아래와 같이 몇 가지 선행작업을 해줘야 한다.

 

 

첫 번째 작업은, 안드로이드 기기에서 네트워크 통신을 하기 위해서는 네트워크 통신과 관련된 '권한(permission)'을 추가해 주는 것이다.

 

그렇다면 네트워크 통신을 하기 위해선 어떤 권한들을 줘야 하는 것일까? 기본적으로는 '인터넷 접근 권한'과 '네트워크  연결 상태 접근 권한'이 두 가지 권한을 주면 된다.

 

아래는 안드로이드 프로젝트를 만들 때 필수적으로 생기는 build 파일 중 [android - app - src] 경로에 존재하는 'AndroidManifest.xml' 파일에 해당 permission 을 추가해 주는 코드를 작성해 본 것이다. 

 

 

<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.apitest">

    <uses-permission android:name="android.permission.INTERNET" />				// 인터냇 접근 권한
    <uses.permission android:name="android.oermisiion.ACCESS_NETWORK_STATE"/>	// 네트워크 상태 접근 권한

    <application>
    ...
    << 내용 생략 >>
    ...
    </application>

</manifest>

 

 

 

 

이 두 가지 권한중 인터넷 permission은 권한을 주지 않으면 런타임 동안 Security Exception 에러가 발생하기에 네트워크 연결을 위해선 해당 권한은 필수적으로 지정해주어야 한다. 또한 네트워크 상태 접근 permission도 해당 권한을 주지 않은 상태에서 API를 사용한다면 Security Exception 에러가 발생하게 된다.

 

(위의 에러는 직접 겪어봐야 와닿을 것 같아 책에 나온 예제대로 새로운 프로젝트를 만들어 해당 에러를 내보려 했으나 예제 10년 전 책이라 그런지 그대로 작성해도 제대로 빌드 자체가 실행되지 않아 이는 나중에 안드로이드 스튜디오를 더 공부한 후 해보는 걸로 결정했다...ㅜ) 

 

 

 

두 번째 작업은 네트워크의 연결상태를 확인하는 것인데, 기기가 네트워크 통신이 가능한 상태인지 알기 위해서는 connectivityManager 클래스의 getActiveNetworkInfo() 함수의 반환값이 'true' 인지 'false'인지를 통해 알 수 있고, getNetworkType 메서드를 통해 연결 중인 네트워크의 Type이 WIFI인지 모바일 데이터인지도 알 수 있다..

참고로 해당 클래스의 메서드를 사용하려면 이 역시 네트워크 상태 접근 권한을 주어야 한다. 그렇지 않으면 똑같이 Security Exception 에러가 발생하게 된다..

 

(관련 실습은 추후에 안드로이드 스튜디오에 대한 공부를 마치면 내용을 추가하거나 글을 따로 남기도록 하겠다.) 

 

 

 

세 번 작업은 네트워크에 대한 연결은 스레드 내에서 진행해야 한다는 것이다. 안드로이드에서 메인스레드는 'UI 스레드'라고도 불리면 사용자 인터페이스와 관련된 기능을 처리해야 하기에 메인 스레드에서는 네트워크 작업과 같은 잠재적으로 시간이 많이 소요되는 작업을 수행하지 못하도록 제한되어 있기에 메인 스레드를 block 하지 않는 일반 스레드에서 네트워크 연동을 시도해야 한다.

 

 

 

이 3가지 세팅을 마쳤다면 본격적으로 HTTP 프로토콜을 이용한 통신에 대해 알아보도록 하겠다. 

 

(현재 진행 중인 프로젝트도 HTTP 프로토콜을 사용 중이며 책에서도 HTTP를 집중적으로 다뤘기에 HTTP에 대해서만 정리해보려 한다,)

 

먼저 HTTP 요청/응답 메시지 구조에 대해 알아보도록 하자. 아래는 HTTP 요청/응답 메시지의 구조이다.

 

 

 

 

요청 메시지 구조

요청라인 GET / test / index.html HTTP/1.1 
헤더 Host: www.test.co.kr 
Connection : close
User-agent: Mozilla /4.0
Accept-language: k0-KR
본문 Data

 

 

 

응답 메시지 구조

상태라인 HTTP/1.1 200 OK
헤더
Connection : close
Date: Thu, 06 Aug 2015
Server: Apache
Last-Modified: Mon, 22, Jun 2015
Content-Length: 6821
Content-Type: text/html
본문 Data

 

 

 

 

여기서 응답 메시지의 상태코드는 요청에 대한 상태코드를 전달받는데, 이상태 코드에 따라 클라이언트 측에서 다시 요청을 할 것인지 다른 작업을 진행할 것인지 등의 동작을 처리하면 된다. 상태코드는 세 자리 정수로 결과를 처리하는데 맨 앞의 백의 자리 숫자가 1,2,3,4,5로 분류되면 뒤에 두 자릿수는 세부적인 내용의 일련번호이다

 

분류 상태코드 내용
information 100~199 서버에서 정보로 클라이언트의 요청이 접수되어 현재 작업중이라는 의미
Success 200~299 클라이언트의 요청작업이 성공적으로 처리되었음을 의미
Redirection 300~399 파일들이 이동되었을 때 이동하는 위치를 응답에 포함하는 것을 의미
Client Error 400~499 클라이언트 요청이 불완전하며, 추가적인 정보가 필요하다는 것을 의미
Server Error 500~599 서버에서 에러가 발생하였으며, 클라이언트 요구를 처리할 수 없는경우를 의미

 

 

 

위의 표는 상태코드에 대한 내용을 정리한 표인데, 아래에서 자주 접하게 된 상태 코드에 대해 한 번 더 다뤄보도록 하겠다.

 

 

 

상태코드 내용
200 성공, 클라이언트 요청을 서버가 제대로 처리한 경우이다.
403 서버가 요청을 거부한 경우에 해당한다.
404 서버에 존재하지 않는 페이지에 대한 요청이 있을 때 발생한다.
500 서버에 오류가 발생하여 요청을 수행할 수 없는 상태이다.
503  서버의 문제로 인하여 일시적으로 요청을 처리할 수 없는 경우에 발생하는 코드이다

 

 

 

HTTP 프로토콜은 기본적으로 웹에서 동작하는 프로토콜이므로 URL을 통해 접속할 서버의 위치와 자원에 접근하며, URL의 형태는 아래와 같다.

 

 

 

 

HTTP 프로토콜과 URL을 사용하여 서버에 요청하는 방법은 사용목적에 따라 분류하면 7가지지만, 이것들 모두가 사용되는 것은 아니며 보통 가장 많이 사용되는 것은 GET과 POST만을 이용하는 것이다. DELETE와 PUT 등이 필요한 경우도 GET과 POST만으로도 충분히 표현 가능하기 때문에 GET과 POST가 많이 사용되고 있다.

 

 

그럼 HTTP 프로토콜에서 클라이언트가 서버에게 요청하는  Method들에 대해 표로 정리하여 자세히 알아보도록 하겠다.

 

 

 

Method 사용 용도
GET 정보를 서버측에 요청하여 가져오기 위해 사용
POST 정보를 서버측에 전달하기 위해 사용
PUT 정보를 서버측에 업데이트하기 위해 사용
DELETE 정보를 서버측에서 삭제하기 위해 사용
HEAD HEAD정보만을 요청하여 해당 자원이 존재하는지 체크하기 위해 사용
OPTIONS 서버가 지원해주는 Method들의 종류를 요청하기 위해 사용
TRACE 클라이언트가 서버 상태를 확인하기 위해 클라이언트의 요청을 바로 반환되는 요청을 보낼 때 사용

 

 

 

책에선 안드로이드 스튜디오에서 제공해주는 안드로이드 SDK를 통해 실제 HTTP 통신을 통해 POST요청과 GET요청을 어떻게 하는지 예제를 보여주었지만 안드로이드 스튜디오 내에서 프로젝트를 진행하여 MainActivity.java 파일을 수정하는 것이기에 현재 나에게는 크게 도움이 될 것 같지 않아 안드로이드 네트워크 통신과 관련된 글은 위의 내용까지만 작성하게 되었다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

반응형