수업 정리

19일차 수업 정리(Network)

Vita500cc 2020. 5. 4. 21:13

용어 정리

 - Network : Terminal(단말)과 Terminal간의 통신
    => Terminal : 입출력기능을 가진 H/W
        -> IP Address(인터넷에서 구분) - IPv4 : 32bit(8bit씩 4개) / IPv6 : 256bit(16bit씩 16개)

 - protocol : 통신 규칙
  ex) TCP/IP(인터넷 프로토콜) -> HTTP, HTTPS(HTTP에서 Security를 추가)
 - Port : 단말에서 Process구분을 하기 위한 번호(0~65535)
 - 자원을 구분하기 위한 주소 : URL, URI(상대 주소), URN(절대주소)


 - IP : Port(통신을 하기 위해 반드시 필요)
   Unicast - 1:1
   Multicast - 1:group
   BroadCast - 1:전체

 - 라우팅 - 최적의 루트를 찾아줌
 - 프록시 - 내부에서 외부로 나가는 것을 막음
 - 방화벽(fire wall) - 외부에서 내부로 들어오는 것을 막음
 - RPC(Remote Procedre Call)

 

 - 스크래핑 - 데이터를 가져옴 
 - 크롤링 - publising + pharsing(데이터를 가져와서 필요한 데이터 추출) 

**Network
    => java.net 패키지
1. InetAddress
    => IP정보를 사용하기 위한 클래스
  1) 클래스 정보 확인
    - abstact class도 아니고 interface 도 아님
    - constructor가 없음
    - 모든 method가 static인지 확인(모든 static이 아님)
    - 자신과 동일한 자료형을 리턴하는 static메소드가 있는지 확인(O)
  2) 인스턴스 생성
    => static InetAddress getLocalHost() : 자신의 단말기의 IP 정보 리턴
    => static InetAddress getByName(String hostName) : hostName에 해당하는 단말기 1개의 IP정보 리턴
    => static InetAddress[] getAllByName(String hostName) : 전체 IP정보를 배열로 리턴
  3) 메소드
    => getHostName(): 호스트 명을 리턴
    => getAddress(): ip 주소를 바이트 배열로 리턴
    => getHostAddress(): ip주소를 문자열로 리턴
    => toString(): ip 주소를 문자열로 변환하여 리턴

2. Socket
    => NIC(Network Interface Card - LAN Card)를 프로그래밍에서 사용하기 위하여 추상화 한 개념
  1) Socket에 따른 통신 방식 구현
    => Low Level 통신 : Socket을 직접 생성하여 사용하는 방식(고효율 고난이도)
    => High Level 통신 : 이미 만들어진 프로토콜을 이용하여 Socket을 직접 생성하지 않고 통신(http, https등의 웹통신)

  2) 전송방식에 따른 분류
    => 연결형 통신(TCP - Stream) : 데이터 교환시, 연결하여 메시지를 주고 받으면서 통신하는 방식(채팅 서비스)
    => 비연결형 통신(UDP - Datagram): 데이터 보내는 곳에서 받는 곳으로 일방적 메시지 전송(Push Message 전송등)
    => http : 연결형 통신이지만 한번 메시지를 주고 받으면 연결을 해제
                (채팅서비스 구현시 http보다 하위의 소켓통신이나 web socket을 이용하는 것이 바람직)

3. java.net.Socket
  1) 소켓 생성
    - Socket(접속할 단말의 IP, 포트번호) : 단말과 접속하고, 통신을 할 수 있도록 생성
  2) 소켓 닫기
    - close()
  3) Socket의 주요 메소드
    => InetAddress getInetAddress() : 상대방 IP 정보 리턴
    => InetAddress getLocalAddress() : 자신의 IP 정보 리턴
    => int getPort() : 상대방 포트 번호
    => int getLocalPort() : 자신의 포트 번호

    => InputStream getInputStream() : 데이터를 읽어오기 위한 스트림 리턴
    => OutputStream getOutputStream() : 데이터를 전송하기 위한 스트림 리턴

  4) www.daum.net의 html(문자열) 가져오기
    => daum은 80번 포트 사용
    => GET http://www.daum.net이라는 요청을 보내면 html 내용을 전송해 줌

4. Stream - TCP 통신
  1) 서버역할을 수행하는 소켓 - ServerSocket
     => 클라이언트의 접속을 대기하는 소켓
  2) 생성자
     => ServerSocket(int port) : 포트번호를 가지고 생성
     => ServerSocket(int port, int backlog) : backlog는 접속 할 수 있는 클라이언트의 수
  3) 메소드
    => Socket accept() : 메소드 호출시 서버는 블럭상태로 대기하다가 클라이언트가 접속시 통신에 필요한 Socket 리턴
    => void close() : 서버소켓을 닫는 메소드
  4) 통신 과정
    (1) 서버 소켓을 생성하여 클라이언트의 접속 대기
    (2) 클라이언트에서 소켓을 생성해서 서버에 연결 요청
    (3) 데이터를 주고 받기
    (4) 소켓 닫기
  5) TCP 소켓 통신
    => 서버 소켓

5. Datagram Socket - 비연결형 통신, UDP 통신
    => 연결하는 과정없이 일방적으로 데이터를 전송하는 방식
    => 수신 상태를 확인 할 수 없는 방식
  1) DatagramSocket 생성자
    - DatagramSocket(int port) : 받는 쪽은 port번호를 설정해서 생성
    - DatagramSocket(int port, InetAddress addr) : IP가 2개 이상일때 직접 IP를 지정
    - DatagramSocket() : 보내는 쪽에서 생성
  2) 메소드
    - void close()
    - void receive(DatagramPacket dp) : 받는 메소드
    - void send(Datagrampacket dp) : 보내는 메소드
  3) DatagramPacket의 생성자
    - DatagramPacket(byte[] buf, int length) : 받는 쪽에서 생성 - 바이트 배열을 만들어서 대입
    - DatagramPacket(byte[] buf, int length, InetAddress addr, int port) : 보내는 쪽에서 생성
  4) 문자열과 바이트 배열
    - 문자열을 바이트 배열로 만들 때 : 문자열.getBytes()
    - 바이트 배열을 문자열로 만들 때 : new String(바이트 배열)
  5) Multicast
    => 그룹 내에 있는 모든 단말기에게 메시지를 전송하는 통신방식
    => UDP 방식을 이용해서 해야하고 IPv4 : 224.0.0.0 ~239.255.255.255 사이 / IPv6 : ff00:: 로 시작하는 IP를 이용
         (Windows는 IPv4, IPv6 둘다 되는데 Mac IPv6만 가능)
    => 보내고 받는 방식은 UDP와 동일, 클래스가 MulticastSocket으로 변경, 그룹 참여시 joinGroup을 호출, 빠져나

        갈 때는 leaveGroup이라는 메소드를 호출
    => 받는 IP와 Port번호 - FF01:0:0:0:0:0:0:175 - 9999

** URL
    => 웹 서버에 데이터를 요청하고 전송받는 통신
    => 고레벨 통신 방식이라서 소켓을 직접 생성할 필요가 없음
1. URL
    => 웹상에서 자원의 고유한 위치

    => 구성 - 프로토콜: //도메인이나 IP : 포트번호/경로?이름=값&이름=값...
    => 프로토콜은 대부분 http나 https로 시작하나,  //로 시작하는 경우 상황에 따라 http or https로 접속
    => 포트 번호는 생략 가능한 경우가 있음, 이경우 프로토콜이 기본적으로 설정된 포트를 이용하여 서버를 만든것
    => 경로도 생략이 가능한 경우가 있음, 이 경우 서버 설정에서 없으면 어떤 파일을 출력하라고 되어 있기 때문
    => 이름=값 형태를 query string이나 parameter라고 함(서버에 전송하는 데이터, 없는 경우도 있음)

2. java에서의 URL 통신
  1) URL을 생성
    URL(String url) : url이 잘못될수 있어 예외처리를 반드시 해주어야 함
  2) URLConnection을 생성
    연결은 URL인스턴스.openConnection() 호출, 

    리턴 인스턴스는 URLConnection -> httpURLConnection으로 강제 형변환
  3) HttpURLConnection을 가지고 옵션을 설정
    - setConnectTimeout(int 초단위시간) : 최대 접속 시간 설정
    - setUseCaches(boolean 캐시 사용여부)
    - setRequestProperty(String name, String value)
    - addRequestProperty(String name, String value)
  4) 데이터 주고 받기
    - HttpURLConnection 객체의 getInputStream()이나 getOutputStream()을 호출해서 스트림을 받아서 사용
    (1) 문자열 받기 : new BufferedReader(new InputStreamReader(con.getInputStream()))
    (2) 파일 다운로드 : new BufferedInputStream(con.getInputStream())
  5) https://drink-vita.tistory.com/ 사이트의 html(문자열) 받아오기 (권한문제로 403오류발생)
  6) 이미지 다운로드로 받아서 저장하기
    => 데이터를 받아와서 사용하는 경우 이 데이터가 이전 데이터와 동일하다면 이전 데이터의 존재여부를 확인하여
        이전 데이터가 존재시 바로 사용, 이전데이터가 존재하지 않거나 업데이트된 경우 다운로드 받는 것이 좋음.
    => 네트워크 입출력은 불확실성이 높은 작업이므로 스레드를 이용할 것을 권장
        (안드로이드 : 네트워크 입출력 작업중 스레드 미사용시 실행되지 않음 / iOS : 마켓에서 reject)
    => 스레드를 만드는 방법
        (1) Thread 클래스로부터 상속받아 run메소드 재정의
        (2) Runnable 인터페이스를 implements해서 run 메소드 재정의

**Open API
    => 이전에는 사용자가 서버에 접속을 하면 데이터를 가지고 View를 만들어서 출력
    => 접속 디바이스 다양해지며, 서버쪽에서 모든 View를 만드는 것이 불가능해졌고, 사용자들이 원하는 형식의 데이

        터가 아닐수 있다는 문제 발생
    => 최근에는 데이터를 가진 곳에서 일반 유저들이 데이터를 가져다 사용할 수 있도록 만들어줌(Open API)
    => Open API는 아무런 과정없이 가져다 사용, 회원가입 및 정보를 입력, 비용을 지불하는 경우등이 있음
        (이러한 데이터를 가져다가 원하는 형식으로 만들어 출력하는 것을 publising이라고 함)

    => URL에 한글이 포함되어 있으면 한글은 인코딩해서 설정해야 함

java.net.URLEncoder.encode(String text, String enctype)
    => enctype에는 utf-8, euc-kr, ms-949등을 대입가능(최근 한글웹에서는 대부분 utf-8만 사용)
    => OpenAPI는 url에 권한 설정을 하는 경우도 있지만(국내 공공 기관 데이터) 카카오나 네이버 구글등은 api사용 권

        한을 프로퍼티 형태로 헤더에 포함하도록 함
    => OpenAPI는 사용법, 권한등이 변경되기도 하므로 openAPI를 이용하여 개발시 도큐먼트을 읽어봐야 함