TIL #25 - 네트워크, I/O
# 네트워크
네트워크는 서로 다른 PC간의 소프트웨어를 이용한 데이터 이동이다.
아래는 네트워크를 숫자형태로 표현한 IP 값을 얻어오는 클래스이다.
IP는 32비트로 XXX.XXX.XXX.XXX 의 형태로 나온다.
import java.net.InetAddress;
import java.net.UnknownHostException;
class InetAddressTest {
public static void main(String[] args) throws UnknownHostException{
InetAddress naver = InetAddress.getByName("www.naver.com");
System.out.println("NAVER IP :" +naver.getHostAddress());
System.out.println();
// 내자신의 ip 얻기
InetAddress local = InetAddress.getLocalHost();
System.out.println("localhost IP : " + local.getHostAddress());
System.out.println();
InetAddress[] ar = InetAddress.getAllByName("www.daum.net");
for(InetAddress data : ar){
System.out.println("Daum IP : " + data.getHostAddress());
}
}
}
어떤 사이트는 IP 주소가 여러개일 수 있다.
그런 경우엔 InetAddress 배열을 이용해서 얻어온다.
InetAddress의 경우엔 new로 생성하면 접근제어자가 public이 아니라는 에러가 뜬다.
따라서 메서드를 통해서 불러줘야한다. (getByName())
어떤 사이트의 프로토콜, 호스트, 포트, 기본포트, 파일을 전부 불러와 본다.
import java.net.URL;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.net.MalformedURLException;
class URLTest {
public static void main(String[] args) throws IOException, MalformedURLException{
URL url = new URL("https://www.naver.com");
System.out.println("프로토콜 = "+ url.getProtocol());
System.out.println("호스트 = "+ url.getHost());
System.out.println("포트 = "+ url.getPort());
System.out.println("기본포트 = "+ url.getDefaultPort());
System.out.println("파일 = "+ url.getFile());
System.out.println();
}
}
port 번호는 0부터 65535까지 이용한다.
HTTP는 80
보안상의 문제로 요즘 많이 사용하는 HTTPS 는 443
파일전송시 사용하는 FTP 는 21
원격시 사용하는 TELNET은 23, TELNET은 보안의 문제로 ssh를 대신 많이 사용한다고 한다.
프로토콜은 서버와 클라이언트간의 통신규약이다.
대표적인 프로토콜로는 TCP, UDP 가 있다.
TCP 는 연결 후 통신하며 신뢰성 있는 데이터를 전송한다.
TCT의 예로는 Socket과 ServerSocket이 있다.
UDP는 연결없이 통신하며 신뢰성없는 데이터를 전송한다.
상대방이 데이터를 받던 받지 않던 보내버린다.
#웹사이트를 통해 특정 단어 뽑아오기
앞서 배웠던 writer와 reader를 통해 웹사이트의 데이터들을 가져온다.
그리고 그 데이터 중에서 14k 라는 단어의 수를 세어본다.
위와 같은 형태로 웹사이트에서 아래의 코드로 데이터들을 가져올 것이다.
웹은 inputStream 타입이기 때문에 InputStreamReader를 이용한다.
만약에 키보드의 System.in 으로 데이터를 받아올 때는 in이 inputStream 타입이므로 역시 InputStreamReader를 이용해서 읽어들인다.
만약 System.out 이라면 out은 printStream 이다.
파일로 들어올 때는 FileReader이다.
import java.net.URL;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.net.MalformedURLException;
class URLTest2 {
public static void main(String[] args) throws IOException, MalformedURLException{
URL url = new URL("http://www.liebli.com/");
먼저 URL 클래스를 통해 위의 사이트의 정보를 가져올 것을 알린다.
위의 사진처럼 InputStreamReader로 buffer에 들어오고 buffer에서 BufferedReader로 자바 파일까지 들어오게 되므로 아래의 코드 처럼 된다.
BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream()));
openStream()은 URL에 의해 참조된 리소스를 연결하고 서버와 클라이언트 연결에 필요한 작업을 처리한 후
데이터를 읽을 수 있는 InputStream으로 반환해준다.
이제 데이터를 읽는데, 데이터는 한 줄 한 줄 씩 읽어내려간다.
먼저 읽어야할 줄 String line을 null로 초기화해준다.
또, 위의 사이트에서 14k 라는 단어만 indexOf를 사용해 뽑아올 예정이기 때문에 idx와
count를 0으로 초기화 해준다.
String line = null;
int idx;
int count = 0;
웹의 데이터를 다 읽을 때까지 while문을 반복하는데, line이 null이 될 때까지 (더 이상 읽을 거리가 없을 때까지) 반복한다.
while((line = br.readLine()) != null){
또, 소문자와 대문자는 다르게 구분되기 때문에 읽어들이는 데이터의 14k를 전부 소문자로 바꿔서 들여보낸다.
line = line.toLowerCase();
이제 indexOf로 웹에 14k 라는 단어가 몇개가 있는지 세어본다.
idx를 0으로 초기화해 시작 위치로 지정한다.
idx가 만약 -1이 된다면 더이상 찾을 것이 없다는 것이므로 -1이 아닌 동안 while문을 돌리도록 한다.
while((idx = line.indexOf("14k", idx)) != -1){
indexOf는 찾는 단어, 찾기를 시작할 인덱스 위치를 매개변수로 사용한다.
count++;
idx = idx+("14k".length());
indexOf가 찾으면 count는 곧장 ++ 을 해준다.
그리고 한 줄에 14k가 2개가 있을 수 있고 3개가 있을 수 있는데, 이는 아무도 모르는 일이다.
그렇기 때문에 항상 idx를 0으로 해두고 0번째부터 찾게 하면 놓치는 것이 많을 것이다.
아래의 예시를 보자
가가가14k가가가가14k가가가가 |
사이트에 위와 같은 한 줄이 주어졌고 이 한 줄에서 14k를 찾아본다.
14k는 두개가 있다.
그런데 만약 찾기를 시작하는 인덱스를 0으로 해버리면 첫번째 14k를 찾고 바로 다시 0으로 돌아가 두번째 14k를 놓치고 만다.
그렇기 때문에 0이 아닌 다른 기준으로도 다시 찾게 만들어야한다.
인덱스는 0부터 시작한다.
그래서 0, 1, 2 가다가 3번 인덱스에서 1을 발견한다.
그렇게 3번부터 5번인덱스까지 14k 가 완성된다.
이렇게 첫번째 14k를 찾게 되면 두번째 14k 찾기를 시작하는 지점은 어느 지점인가?
답은 첫번째로 찾은 14k의 인덱스가 끝나는 시점부터 이다.
즉, 5번인덱스까지가 14k 단어의 인덱스였기 때문에 6번 인덱스부터 다시 찾기 시작해야한다.
idx = idx+("14k".length());
따라서 맨 처음에 찾기 시작한 시점에서 14k를 찾았다면, 맨 처음 찾기 시작한 시점에서 찾은 14k의 길이만큼 더해준 값이 다시 탐색시작 위치가 된다.
while문은 더 이상 읽을 게 없으면 빠져나온다.
}
}// while
System.out.println("14k의 개수 = " + count);
br.close();
}
}