1. 방화벽(firewall) 과 proxy
1) 방화벽
=>외부 컴퓨터에서 내 컴퓨터로 들어올 때 거치는 프로그램이나 하드웨어
=>방화벽이 설정되어 있으면 외부 컴퓨터에서 내 컴퓨터로 들어오는 것을 차단할 수 있습니다.
=>Windows에서는 [제어판] - [Windows 방화벽] 메뉴에서 설정하거나 해제 가능
=>Mac에서는 Apple 메뉴 -> 시스템 환경 설정 -> 보안 및 개인정보 보호 -> 방화벽
=>리눅스에서는 firewall 명령어로 수행
2) proxy
=>내 컴퓨터에서 외부 컴퓨터로 나갈 때 거치는 프로그램이나 하드웨어
=>특정 사이트에 접근하는 것을 막거나 흔적을 남기기 위해서 사용
2. 비연결형 통신(UDP 프로토콜)
=>데이터를 일방적으로 전송하는 방식
=>받는 쪽에서 수신 여부를 송신측에 알려주지 않기 때문에 신뢰성은 떨어집니다.
=>불필요한 연결 동작이 없기 때문에 일반적으로 속도는 TCP 방식보다는 빠릅니다.
=>중요하지 않은 단순한 메시지 전송에 이용하는 경우가 많은데 Call Center에서 메시지를 전송할 때 사용합니다.
=>Java에서는 DatagramSocket 클래스를 이용해서 UDP 통신을 구현
1) DatagramSocket: UDP 전송을 위해서 필요한 클래스
- 생성자
DatagramSocket(): 데이터를 전송하는 쪽에서 사용하는 소켓
DatagramSocket(int port): 데이터를 받는 쪽에서 사용하는 소켓
=>받는 쪽은 아이피 주소와 포트번호를 알려줘야만 보내는 쪽에서 접속을 할 수 있습니다.
- 주요 메소드
void close(): 소켓 닫는 메소드
void receive(DatagramPacket p): 데이터를 전송받기 위한 메소드
=>DatagramePacket 변수만 대입하면 보내는 쪽에서 보내주는 데이터를 받을 수 있습니다.
void send(DatagramPacket p): 데이터를 전송하기 위한 메소드
=>전송하는 쪽에서는 DatagramPacket의 내용을 채워서 보내야 합니다.
2) DatagramPacket: UDP 전송에 필요한 데이터를 만들기 위한 클래스
- 생성자
DatagramPacket(byte[] buf, int length): 데이터를 전송받기 위한 패킷을 만들 때 사용하는 생성자로 바이트 배열과 크기를 대입하는데 length 만큼 buf에 저장합니다.
DatagramPacket(byte[] buf, int length, InetAddress address, int port): 데이터를 전송하기 위한 패킷을 만들 때 사용하는 생성자로 buf에 전송할 내용을 대입하고 length에는 전송할 길이를 address에는 받을 곳의 주소를 port에는 받을 곳의 포트번호를 설정하면 됩니다.
- 메소드
InetAddress getAddress(): 받는 쪽에서 보내는 쪽의 주소를 알고자 할 때 사용하는 메소드
byte[] getData(): 받는 쪽에서 보내는 쪽에서 보내준 데이터를 확인하고자 할 때 사용하는 메소드
int getLength(): 데이터의 길이
int getPort(): 보내는 쪽의 포트 번호
메시지를 전송받아서 출력하는 UDP Server 클래스
package udpunicast;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
//UDP 전송을 받기 위한 클래스
public class UDPServer {
public static void main(String[] args) {
//try()안에서 객체를 생성하면 닫지 않아도 try 구문이
//끝나면 자동으로 close()를 호출합니다.
try(DatagramSocket dsocket = new DatagramSocket(7777)) {
//무한 반복해서 받기
while(true) {
System.out.println("서버 대기 중....");
//데이터를 저장할 byte 배열을 생성
byte [] b = new byte[128];
//데이터를 전송받을 DatagramPacket 생성
DatagramPacket dp =
new DatagramPacket(b, 128);
//클라이언트로부터 데이터 받기
dsocket.receive(dp);
//데이터 해석
//보낸 곳 확인
System.out.println("보낸 곳:" + dp.getAddress());
//보낸 데이터 확인
//받은 데이터를 문자열로 변환: 공백을 제거
String msg = new String(b);
msg = msg.trim();
System.out.println("보낸 메시지:" + msg);
}
}
//try 구문안에서 예외가 발생했을 때 처리하는 구문
catch(Exception e) {
//예외의 내용을 콘솔에 출력
System.out.println("예외:" + e.getMessage());
//예외의 위치를 확인하기 위해서 예외를 역추적합니다.
e.printStackTrace();
}
}
}
메시지를 전송하는 클래스
package udpunicast;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Scanner;
public class UDPClient {
public static void main(String[] args) {
//데이터를 보내기 위한 소켓을 생성
try(DatagramSocket dsocket = new DatagramSocket();
Scanner sc = new Scanner(System.in)) {
while(true) {
//전송할 데이터 생성
System.out.print("전송할 메시지:");
String msg = sc.nextLine();
//데이터를 전송할 곳의 주소를 생성
InetAddress addr =
InetAddress.getByName("192.168.0.200");
int port = 7777;
//데이터 패킷을 생성
DatagramPacket dp =
new DatagramPacket(msg.getBytes(),
msg.getBytes().length, addr, port);
//데이터 전송
dsocket.send(dp);
System.out.println("메시지 전송 성공");
}
}
catch(Exception e) {
System.out.println("예외:" + e.getMessage());
e.printStackTrace();
}
}
}
3) Multicast 전송
=>그룹 통신 - 그룹에 속한 모든 컴퓨터가 메시지를 주고 받을 수 있는 통신
=>화상회의에 주로 이용
=>224.0.0.0 - 239.255.255.255 사이의 주소를 이용해야 합니다.
=>MulticastSocket 클래스를 이용하고 전송방법은 UDP와 동일합니다.
- 생성자
MulticastSocket(): 보내기 위한 소켓
MulticastSocket(int port): 받기 위한 소켓
- 메소드
joinGroup(InetAddress addr): 그룹에 참여
leaveGroup(InetAddress addr): 그룹에서 탈퇴
- 과정
->필요한 멀티캐스트 소켓 객체를 생성
->그룹에 참여
->데이터를 주고 받기
->그룹에서 빠져 나오기
멀티캐스트 전송을 받기 위한 클래스
package multicast;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
//멀티캐스트 전송을 받기 위한 클래스
public class MulticastServer {
public static void main(String[] args) {
//멀티 캐스트 가능한 소켓 생성
try(MulticastSocket ms = new MulticastSocket(9999)) {
//그룹에 참여
ms.joinGroup(InetAddress.getByName("230.0.0.1"));
while(true) {
//메시지를 저장하기 위한 배열 생성
byte [] b = new byte[256];
//메시지와 전송한 곳의 정보를 저장하기 위한
//패킷 객체 생성
DatagramPacket dp =
new DatagramPacket(b, b.length);
//데이터 전송 받기
ms.receive(dp);
//받은 데이터를 가지고 메시지 만들기
String msg = new String(dp.getData());
msg = msg.trim();
System.out.println(msg);
}
}catch(Exception e) {
System.out.println("예외:" + e.getMessage());
e.printStackTrace();
}
}
}
멀티캐스트 전송을 하기 위한 클래스
package multicast;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.util.Scanner;
public class MulticastClient {
public static void main(String[] args) {
try(MulticastSocket ms = new MulticastSocket();
Scanner sc = new Scanner(System.in)) {
System.out.print("닉네임 입력:");
String nick = sc.nextLine();
//전송할 IP 주소와 포트번호
InetAddress addr =
InetAddress.getByName("230.0.0.1");
int port = 9999;
while(true) {
System.out.print("메시지 입력:");
String msg = sc.nextLine();
msg = nick + ":" + msg;
//메시지를 전송하기 위한 패킷 생성
DatagramPacket dp =
new DatagramPacket(msg.getBytes(),
msg.getBytes().length, addr, port);
ms.send(dp);
System.out.println("전송 성공!!!!");
}
}catch(Exception e) {
System.out.println("예외:" + e.getMessage());
e.printStackTrace();
}
}
}
3. URL 통신
=>주소를 Domain을 사용하는 통신 방식
1) URL
- URL 지정 방식
프로토콜://도메인이나 IP주소:포트번호/파일경로?파라미터
=>파라미터는 이름=값 의 형태로 여러개 사용이 가능
=>프로토콜의 기본 포트를 사용하는 경우는 포트번호는 생략할 수 있습니다.
HTTP 프로토콜은 기본 포트번호가 80 - Web
HTTPS 프로토콜은 기본 포트번호가 443 - 보안이 적용된 Web
FTP: 파일 전송 프로토콜
SMTP: 메일을 보내기 위한 프로토콜
POP3: 메일을 받기 위한 프로토콜
DNS: 도메인을 IP 주소로 변경해주는 프로토콜
DHCP: 동적으로 IP를 할당하는 프로토콜
Telnet: 원격접속 프로토콜
=>파일경로는 서버 설정에 따라 생략이 가능
=>파라미터는 서버에게 보내는 데이터로 이름과 값을 같이 전송
=>전송방식에 따라 파라미터는 보이지 않는 경우도 있습니다.
=>파라미터에 한글이 포함된 경우는 인코딩해서 전송해야 합니다.
=>파라미터는 서버에게 전송할 데이터가 없는 경우 생략이 가능
- URL 클래스
=>Java에서 사용하는 URL 정보를 저장하기 위한 클래스
=>생성자
URL("경로")
URL("프로토콜", "도메인", "포트번호", "파일경로")
=>메소드
URLConnection openConnection(): url에 연결을 할 수 있는 URLConnection 객체를 리턴해주는 메소드
위의 메소드를 호출해서 사용할 때는 리턴되는 데이터를 반드시 형변환 해서 사용해야 합니다.
URLConnection은 추상 클래스로 HttpURLConnection, HttpsURLConnection, JarURLConnection의 상위 클래스입니다.
URL에 따라 적절한 Connection 클래스 타입으로 변환해서 사용해야 합니다.
2) HttpURLConnection 클래스
=>웹에 연결해서 데이터를 받아오는 클래스
=>직접 생성하지 않고 URL 객체의 openConnection으로 부터 리턴받아서 생성
=>메소드
void setConnectTimeout(int timeout): 연결 시도 시간을 설정하는 메소드로 1/1000초 단위로 설정합니다.
이 설정을 반드시 해주어야 하는데 이 설정을 하지 않으면 서버에 접속이 안될 때 무한대기에 빠지게 됩니다.
void setUseCaches(boolean newValue): 캐시 사용 여부를 설정
Cache: 자주 접속하는 사이트의 경우 사이트의 정보를 클라이언트에 저장하고 있다가 다음에 접속할 때 웹에서 가져오지 않고 클라이언트에 있는 데이터를 출력하기 위해 사용하는 것
CPU <-----------------> MainMemory(RAM)
|
|
Cache(자주 사용하는 데이터) - CPU가 Cache에서 먼저 데이터를 찾고 없으면 RAM으로 갑니다.
void setRequestMethod(String method): 전송 방식을 설정(GET, POST)
int getResponseCode(): 응답코드를 리턴
InputStream getInputStream(): 웹에서 읽을 수 있는 스트림 리턴
실습) 웹페이지의 html 다운로드
package url;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
public class WebText {
public static void main(String[] args) {
try {
//웹에 접속할 URL 만들기
URL url = new URL("https://www.youtube.com/");
//연결 객체 생성
HttpURLConnection con =
(HttpURLConnection)url.openConnection();
//데이터를 읽을 수 있는 스트림을 생성
//문자열을 읽을 수 있는 스트림 만들기
BufferedReader br =
new BufferedReader(
new InputStreamReader(
con.getInputStream()));
//줄 단위로 데이터 읽기
while(true) {
//한 줄의 데이터를 읽기
String line = br.readLine();
//읽은 게 없으면 중단
if(line == null) {
break;
}
//데이터를 읽었으면 출력
System.out.println(line);
}
br.close();
con.disconnect();
}catch(Exception e) {
System.out.println("예외:" + e.getMessage());
e.getMessage();
}
}
}
3) Thread
=>작업을 수행하고 있는 도중에 다른 스레드로 제어권을 이동시켜 작업을 수행할 수 있도록 해주는 것
- Thread 클래스 상속받아서 생성
=>Thread 클래스를 상속받는 클래스를 만들고 run 메소드를 재정의
=>생성한 클래스의 객체를 만들고 start()를 호출
- Runnable 인터페이스를 implements 해서 생성
=>Runnable 인터페이스를 구현한 클래스를 만들고 run 메소드를 재정의
=>생성한 클래스의 객체를 만들고 이 객체를 Thread 클래스의 생성자에 대입해서
Thread 객체를 만들고 start()를 호출
실습) 스레드를 이용해서 웹에서 텍스트 받아오기
package url;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
public class TextDownloadThread extends Thread {
//스레드로 수행할 동작을 작성할 메소드
public void run() {
try {
//웹에서 다운로드를 받기 위해서는
//다운로드 받을 주소를 URL 클래스의 객체로 생성
URL url = new URL("http://www.tjoeun.co.kr/");
//웹 주소에 연결할 Connection 객체 생성
HttpURLConnection con =
(HttpURLConnection)url.openConnection();
//옵션 설정
//접속시도 시간 설정 - 30초
con.setConnectTimeout(30000);
//캐시 사용 여부 설정 - 자주 변하는 사이트는 반드시 설정
con.setUseCaches(false);
//정상응답을 했다면
if(con.getResponseCode() == 200) {
//문자열을 읽을 수 있는 스트림 객체를 생성
BufferedReader br =
new BufferedReader(
new InputStreamReader(
con.getInputStream()));
while(true) {
String line = br.readLine();
if(line == null) {
break;
}
System.out.println(line);
}
br.close();
}else {
System.out.println("데이터를 받아오는데 실패");
}
con.disconnect();
}catch(Exception e) {
System.out.println("예외:" + e.getMessage());
e.printStackTrace();
}
}
}
실습) 웹에서 파일 받기
=>파일을 다운로드받을 때는 BufferedInputStream을 이용해서 다운로드받고 다운로드 받은 내용을 PrintStream을 이용해서 기록해야 합니다.
=>데이터를 서버에서 다운로드 받아 저장하는 방법입니다.
package java0119;
import java.io.BufferedInputStream;
import java.io.PrintStream;
import java.net.HttpURLConnection;
import java.net.URL;
public class FileDownloadThread implements Runnable {
@Override
public void run() {
try {
String addr =
"http://www.onlifezone.com/files/attach/images/962811/376/321/005/2.jpg";
URL url = new URL(addr);
HttpURLConnection con =
(HttpURLConnection)url.openConnection();
con.setConnectTimeout(20000);
con.setUseCaches(false);
if(con.getResponseCode() == 200) {
//파일이름을 만들기
String [] ar = addr.split("/");
String filename = ar[ar.length-1];
//웹에서 파일의 내용을 읽어올 객체 만들기
BufferedInputStream bis =
new BufferedInputStream(
con.getInputStream());
//파일에 기록을 할 스트림
PrintStream ps = new PrintStream(filename);
while(true) {
//128바이트 단위로 읽기
byte [] b = new byte[128];
int r = bis.read(b);
//읽은 게 없으면 중지
if(r <= 0) {
break;
}
//읽은 내용을 파일에 기록
ps.write(b, 0, r);
}
ps.flush();
ps.close();
bis.close();
}else {
System.out.println("다운로드 할 수 없습니다.");
}
con.disconnect();
}catch(Exception e) {
System.out.println("예외:" + e.getMessage());
e.printStackTrace();
}
}
}
'IT > JAVA (17.12.18~)' 카테고리의 다른 글
23일 JAVA(23) - 자바 달력(JAVA Calendar) (0) | 2018.02.05 |
---|---|
22일 JAVA(22) (0) | 2018.01.24 |
21일 JAVA(21) (0) | 2018.01.23 |
20일 JAVA(20) (0) | 2018.01.16 |
19일 JAVA(19) (0) | 2018.01.16 |