Upload
everly
View
113
Download
0
Embed Size (px)
DESCRIPTION
6. 네트워크와 서비스. 네트워크 (1/4). 사용자는 API 들과 네트워크 프로토콜들을 사용함으로써 하위 계층에서 데이터를 전달하는 방법 , 데이터의 신뢰성 등에 대한 걱정 없이 하위 레벨인 애플리케이션 쪽에만 집중할 수 있음. 노드 (Node) : 네트워크란 특정 주소를 가진 기기들이 서로 연결되어 데이터 송수신이 가능한 것을 말함 . 특정 주소를 가진 기기들을 ‘ 노드 ’ 라 함. 네트워크 (2/4). 레이어와 프로토콜 - 프로토콜 : 통신을 위한 규약 및 방법들을 사전에 정의한 것 - PowerPoint PPT Presentation
Citation preview
Unlocking Android
네트워크 (1/4)
2
사용자는 API 들과 네트워크 프로토콜들을 사용함으로써
하위 계층에서 데이터를 전달하는 방법 , 데이터의 신뢰성
등에 대한 걱정 없이 하위 레벨인 애플리케이션 쪽에만 집중할
수 있음
노드 (Node)
: 네트워크란 특정 주소를 가진 기기들이 서로 연결되어 데이터
송수신이 가능한 것을 말함 . 특정 주소를 가진 기기들을 ‘노드’라 함
Unlocking Android
네트워크 (2/4)
3
레이어와 프로토콜
- 프로토콜 : 통신을 위한 규약 및 방법들을 사전에 정의한 것
- 레이어 : 네트워크 프로토콜 스택의 각 부분을 추상화한 것
- Link Layer : 물리적인 장치와 주소를 묶어주는 역할
ARP/RARP 등과 같은 물리 주소 변환 프로토콜들을 포함
- Internet Layer : 주소변환과 데이터 구성을 담당
IP 의 여러 버전과 ping 프로토콜 , ICMP 등이 있음
- Transport Layer : 실제 데이터 전송 . HTTP, FTP, SMTP, IMAP,
POP, DNS,
SSH, SOAP 등의 등용 레벨 프로토콜들을 포함
Unlocking Android
네트워크 (3/4)
4
IP 레이어 : IP 주소를 할당하고 데이터를 전송 단위인 패킷
(Packet) 으로 나누어 전송하는 일을 담당하는데 패킷을 데이터그램
(Datagram) 으로 표현 . 헤더정보 등을 포함하여 한 번에 보낼 수
있는 데이터의 크기 (MTU) 등을 정의
- IP 주소 : 각 패킷의 발신지와 송신지를 알려줌
- 32bit IP 주소는 IPv4 로써 네 개의 섹션으로 나누어 10 진수로 표현
- ‘127‘ 로 시작 : 항상 사용하는 시스템의 루프백 / 로컬주소 나타냄
- ‘10/192’ : 라우팅이 불가능한 주소 . 같은 로컬 네트워크 세그먼트 안에
있는 기기들끼리는 통신할 수 있지만 외부 네트워크에
존재하는 기가들과는 불가능
- IP 네트워크에서의 패킷 라우팅 작업은 라우터에 의해서 결정됨
Unlocking Android
네트워크 (4/4)
5
TCP 와 UDP
- TCP : 여분의 데이터를 추가하여 패킷들의 순서를 처리하고
패킷이
정확히 도착했을 경우 ACK(acknowledgement) 를 통해
정확하게 도착했는지 확인하므로 데이터 전송의 신뢰성을
기대할 수 있음 .
- UDP : 순서대로 데이터 패킷을 보내거나 ACK 를 받는 부분이
없어
단순히 데이터 전송만 할 뿐 상대방에게 제대로
전달되었는지에 대해서는 책임지지 않음 .애플리케이션 레이어 프로토콜
: TCP/UDP 를 사용하는 트랜스포트 레이어에서 패킷이 전달되면
애플리케이션이 이 내용을 처리함 .
Unlocking Android
클라이언트와 서버
6
데이터는 하나의 통일된 형태로 중앙 서버에 저장되고 ,
클라이언트는 데이터를 검색하거나 데이터를 이용한 작업을
하기 위해 HTTP 와 같은 프로토콜을 사용하여 서버에 접속함
다양한 목적으로 하나의 IP 주소를 사용하는 서버에 동시에
접속하는 많은 클라이언트를 처리하기 위해 포트 사용 .
- Well known Ports : 0 ~ 1023
- Registered Ports : 1024 ~ 49151
- Dynamic/Private Ports : 49152 ~ 65535
Unlocking Android
서버 소켓을 이용한 통신
7
서버 소켓 : 특정 IP 주소와 포트에 대해 데이터를 쓰거나 읽을 수
있는 스트림을 의미
소켓을 사용함으로써 데이터의 형태나 패킷 크기 등의 걱정없이
데이터를 전송할 수 있게 해주며 네트워크의 추상화를 통하여
프로그래머의 수고를 덜어줌
소켓을 사용한다는 것은 오늘날 시스템에서 사용하는 POSIX
표준을 따른다는 것을 의미하므로 소켓과 관련된 모든 작업을 파일
I/O 형태로 처리해야 함
Unlocking Android
소켓 사용 예제 (1/2)
8
public final class EchoServer extends Thread { private static final int PORT = 8889; private EchoServer() {} public static void main(String args[]) { EchoServer echoServer = new EchoServer(); if (echoServer != null) { echoServer.start();
} } public void run() { // 서버의 시작 부분
try { ServerSocket server = new ServerSocket(PORT, 1); // java.net.ServerSocket 사용
while (true) { Socket client = server.accept(); // 각 클라이언트를 위한 java.net.ServerSocket 사용
System.out.println(“Client connected”); while (true) { BufferedReader reader =
new BufferedReader(new InputStreamReader(client.getInputStream())); // BufferedReader 로 입력된 내용
읽어오기 System.out.println(“Read from client”);
지정된 포트를 감시
각 클라이언트는 소켓을 구현
Unlocking Android
소켓 사용 예제 (2/2)
9
String textLine = reader.readLine() + “\n”; if (textLine.equalsIgnoreCase(“EXIT/n”)) { // “EXIT” 를
입력받으면 루프종료 System.out.println(“EXIT invoked, closing client”);
break; } // BufferedWriter 를 사용하여 에코 전송
BufferedWriter writer = new BufferedWriter( new OutputStreamWriter(client.getOutputStream())); System.out.println(“Echo input to client”); writer.write(“ECHO from server: “ + textLine, 0, textLine.length() + 18); writer.flush(); } client.close(); } } catch (IOException e) { System.err.println(e); } }}
입력한 내용이 ‘ EXIT’ 가 아닌 경우 서버는 수신된 데이터를 클라이언트의 OutputStream 에 뿌려줌
Unlocking Android
안드로이드 클라이언트의 에코 서버 호출 (1/2)
10
/* 패키지 명 및 import 구분 생략 */public class SimpleSocket extends Activity {
/* 뷰 변수 선언 부분 생략 */ @Override public void onCreate(final Bundle icicle) { super.onCreate(icicle); this.setContentView(R.layout.simple_socket);
/* 뷰 확장 부분 생략 */ this.socketButton.setOnClickListener(new OnClickListener() { public void onClick(final View v) { socketOutput.setText(""); String output = callSocket(ipAddress.getText(). toString(), port.getText().toString(), socketInput.getText().toString()); socketOutput.setText(output); // 텍스트뷰에 출력될 내용 설정 } }); } private String callSocket(final String ip, final String port, final String socketData) { Socket socket = null; BufferedWriter writer = null; BufferedReader reader = null; String output = null; try { socket = new Socket(ip, Integer.parseInt(port)); // 클라이언트측의 소켓 생성
callSocket 메서드 사용
Unlocking Android
안드로이드 클라이언트의 에코 서버 호출 (2/2)
11
writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); reader = new BufferedReader(new InputStreamReader(socket.getInputStream())); String input = socketData; writer.write(input + "\n", 0, input.length() + 1); writer.flush(); output = reader.readLine(); // 소켓의 출력 데이터 읽기 Log.d(Constants.LOGTAG, " " + SimpleSocket.CLASSTAG + " output - " + output); writer.write("EXIT\n", 0, 5); writer.flush(); } catch (IOException e) { Log.e(Constants.LOGTAG, " " + SimpleSocket.CLASSTAG + " IOException calling socket", e); } finally { try { writer.close(); } catch (IOException e) { } try { reader.close(); } catch (IOException e) { } try { socket.close(); } catch (IOException e) { } } return output; }; }
출력을 위한 BufferedReader 설정
입력을 위한 BufferedWriter 설정소켓에 내용 쓰기
Unlocking Android
HTTP 사용하기
12
데이터 전송이 가능한 서버 프로그램이 이미 존재하고 그것을 사용할
수 있다면 , 가장 많이 사용되는 방법이 HTTP 기반의 웹 서버를
사용하는 것이다 .
소켓과 관련된 처리는 HTTP 서버가 알아서 해주기 때문에
안드로이드 클라이언트 애플리케이션에 초점을 맞춘다 .
HTTP 는 상태를 유지하지 않는 프로토콜로서 사용자로
하여금 서버 쪽에 요청을 보내고 서버로부터 이에 대한 응답을
받을 수 있는 몇 가지 방법들을 제공한다 .
Unlocking Android
java.net.UrlConnection 을 보여주는 예제 (1/2)
13
public class SimpleGet extends Activity {. . .
public void onCreate(Bundle icicle) {. . .
this.getButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) { getOutput.setText(""); String output = getHttpResponse(getInput.getText().toString()); // 화면에 출력하기 위해 if (output != null) { getOutput.setText(output); } } }); }; private String getHttpResponse(String location) { String result = null; URL url = null; Log.d(Constants.LOGTAG, " " + SimpleGet.CLASSTAG + " location = " + location); try { url = new URL(location); // 여러 가지 세부사항을 처리하는 URL 오브젝트 생성 Log.d(Constants.LOGTAG, " " + SimpleGet.CLASSTAG + " url = " + url); } catch (MalformedURLException e) { Log.e(Constants.LOGTAG, " " + SimpleGet.CLASSTAG + " " + e.getMessage()); }
getHttpResponse 메서드 호출
Unlocking Android
java.net.UrlConnection 을 보여주는 예제 (2/2)
14
if (url != null) { try { HttpURLConnection urlConn = (HttpURLConnection) url.openConnection(); BufferedReader in = new BufferedReader (new InputStreamReader(urlConn.getInputStream())); String inputLine; int lineCount = 0; // limit the lines for the example while ((lineCount < 10) && ((inputLine = in.readLine()) != null)) { lineCount++; Log.v(Constants.LOGTAG, " " + SimpleGet.CLASSTAG + " inputLine = " + inputLine); result += "\n" + inputLine; } in.close(); urlConn.disconnect(); // 수신 및 연결 종료 } catch (IOException e) { Log.e(Constants.LOGTAG, " " + SimpleGet.CLASSTAG + " " + e.getMessage()); } } else { Log.e(Constants.LOGTAG, " " + SimpleGet.CLASSTAG + " url NULL"); } return result; } }
HttpURLConnection 을 사용하여 서버에 연결 설정
출력을 위한 BufferedReader 생성
데이터 읽기
메서드를 사용하여 리턴 받은 문자열 뒤에 내용 추가
Unlocking Android
아파치 HttpClient API 사용 예제 (1/2)
15
public class ApacheHTTPSimple extends Activity { . . . private final Handler handler = new Handler() {
@Override public void handleMessage(final Message msg) { progressDialog.dismiss(); String bundleResult = msg.getData().getString("RESPONSE"); output.setText(bundleResult); } };
. . . private void performRequest() { final ResponseHandler<String> responseHandler = new ResponseHandler<String>() { public String handleResponse(HttpResponse response) { StatusLine status = response.getStatusLine(); Log.d(Constants.LOGTAG, " " + ApacheHTTPSimple.CLASSTAG + " statusCode - " + status.getStatusCode()); Log.d(Constants.LOGTAG, " " + ApacheHTTPSimple.CLASSTAG + " statusReasonPhrase - " + status.getReasonPhrase()); HttpEntity entity = response.getEntity(); String result = null; try { result = StringUtils.inputStreamToString(entity.getContent());
안드로이드에서는 HTTP 와 다중 스레드를 쉽게 사용할 수 있도록 해주는 java.net 클래스들을 더욱 잘 추상화 시킨 아파치 HttpClient 라이브러리 형태의 API 를 제공하고 있다 .
서로 다른 스레드에서 메시지를 주고받을 수 있는 헨들러 생성
핸들러를 사용하여 UI 업데이트
비동기 HTTP 사용을 위한 ResponseHandler 생성
handleResponse 콜백 구현
HTTP 응답 내용 받아오기
Unlocking Android
아파치 HttpClient API 사용 예제 (2/2)
16
Message message = handler.obtainMessage(); Bundle bundle = new Bundle(); bundle.putString("RESPONSE", result); message.setData(bundle); handler.sendMessage(message); } catch (IOException e) { Log.e(Constants.LOGTAG, " " + ApacheHTTPSimple.CLASSTAG, e); } return result; } }; this.progressDialog = ProgressDialog.show(this, "working . . .", "performing HTTP request"); new Thread() { // HTTP 호출을 위한 새로운 스레드 생성 @Override public void run() { try { DefaultHttpClient client = new DefaultHttpClient(); HttpGet httpMethod = new HttpGet(urlChooser.getSelectedItem().toString()); client.execute(httpMethod, responseHandler); } catch (ClientProtocolException e) { Log.e(Constants.LOGTAG, " " + ApacheHTTPSimple.CLASSTAG, e); } catch (IOException e) { Log.e(Constants.LOGTAG, " " + ApacheHTTPSimple.CLASSTAG, e); } } }.start(); } }
HttpGet 오브젝트 생성
HttpClient 를 사용하여 HTTP 실행
Unlocking Android
HC, PH, AH 의 관계 다이어그램
17
Non UI Thread – network request
Apache HttpClient
execute(method,
responseHandler)
Apache HttpClient
execute(method,
responseHandler)
Apache HttpClient
execute(method,
responseHandler)UI Thread – UI updates
HTTP request
HTTP response
HTTPserver
Unlocking Android
웹서비스
18
모호하게 사용되는 마케팅 용어 ? 명확한 표준 프로토콜 ?
기술 중립적인 네트워크 호스트들을 넘어 API 를 제공하는
수단 . 원격 메서드를 호출하거나 , 특정 플랫폼이나 벤더에
종속적이지 않고 독립적인 명력을 수행하여 원하는 결과를
얻게 하는 기술
POX : 기본적으로 HTTP 기반에서 XML 의 형태로 나타냄
REST : 리소스 개념을 사용하며 , HTTP 메서드와는 다르게 URL
형태로 접근하여 더 자세하게 데이터를 정의
SOAP : 가장 공식적인 방법으로 데이터 타입과 전송 메커니즘 및
보안에 대해 엄격한 규칙을 요구
Unlocking Android
POX – HTTP 와 XML 의 조합 (1/2)
19
public class DeliciousRecentPosts extends Activity { private static final String CLASSTAG = DeliciousRecentPosts.class.getSimpleName(); private static final String URL_GET_POSTS_RECENT = "https://api.del.icio.us/v1/posts/recent?";
. . . private final Handler handler = new Handler() { @Override public void handleMessage(final Message msg) { progressDialog.dismiss(); String bundleResult = msg.getData().getString("RESPONSE"); output.setText(parseXMLResult(bundleResult)); } }; @Override public void onCreate(final Bundle icicle) { super.onCreate(icicle); this.setContentView(R.layout.delicious_posts);
. . . this.button.setOnClickListener(new OnClickListener() { public void onClick(final View v) { output.setText(""); performRequest(user.getText().toString(), pass.getText().toString()); } }); };
del.icio.us URLPOX 서비스 사용은 URL 지정부터
시작핸들러를 사용하여 UI 업데이트
ID 와 패스워드로 로컬 performRequest를 호출하고 HttpClient 실행
사용자 ID 와 비밀번호를 가지고 HTTPS를 사용하는 사이트에 접속하여 최근 포스트 내용 혹은 북마크 목록을 읽어오는 예제
Unlocking Android
POX – HTTP 와 XML 의 조합 (2/2)
20
private void performRequest(final String user, final String pass) { this.progressDialog = ProgressDialog.show(this, "working . . .", "performing HTTP post to del.icio.us"); final ResponseHandler<String> responseHandler = HTTPRequestHelper.getResponseHandlerInstance(this.handler); new Thread() { public void run() { HTTPRequestHelper helper = new HTTPRequestHelper(responseHandler); helper.performPost(DeliciousRecentPosts.URL_GET_POSTS_RECENT, user, pass, null, null); } }.start(); } private String parseXMLResult(String xmlString) { StringBuilder result = new StringBuilder(); try { SAXParserFactory spf = SAXParserFactory.newInstance(); SAXParser sp = spf.newSAXParser(); XMLReader xr = sp.getXMLReader(); DeliciousHandler handler = new DeliciousHandler(); xr.setContentHandler(handler); xr.parse(new InputSource(new StringReader(xmlString))); List<DeliciousPost> posts = handler.getPosts(); for (DeliciousPost p : posts) { result.append("\n" + p.getHref()); } } catch (Exception e) { Log.e(Constants.LOGTAG, " " + DeliciousRecentPosts.CLASSTAG + " ERROR - " + e); } return result.toString(); } }
HTTP 를 위한 helper 사용
XML 을 사용 가능한 형태로 바꾸기 위해서 parseXMLResult 메서드 사용
Unlocking Android
REST
21
특정 리소스를 URI 형태로 만들고 서로 다른 액션을
수행하기 위해 다른 프로토콜 메서드를 사용한다 .
HTTP 에서 여러 가지 다른 작업을 수행하기 위해
POST(create, update, delete), GET(read),
PUT(create, replace), DELETE(delete) 등의 다양한
메소드를 활용하고 있다 .실제로 진정한 REST 구현은 많이 볼 수 없고 , REST
스타일의 API 를 더 많이 사용한다 .