본문 바로가기

JAVA 공책/수업 메모

MulticastSoket

큰 주제


{Multicast 전송}

- 그룹 내의 모든 곳에 데이터를 전송하는 방식의 통신
- UDP통신 방식을 이용하고 D class의 주소를 이용합니다.
- MulticastSocket 클래스를 이용하는데 받는 쪽은 포트 번호를 대입해서 생성하고 보내는 쪽은 포트번호 없이 생성합니다.
- joinGroup과 leaveGroup이라는 메소드를 이용해서 그룹에 참여하거나 빠져나올 수 있습니다.
- 230.100.50.5는 IPv4로 입력한 주소이고 FF7E:230::1234는 ipv6로 입력한 주소입니다.

멀티캐스트 전송을 받는 쪽

package multicast;
public class MulticastReceive {
     public static void main(String[] args) {
         try {
              //받는 멀티캐스트 소켓 만들기
              MulticastSocket ms     = new MulticastSocket(9999);
              //그룹에 참여 - 224.0.0.0부터 239.255.255.255 사이의 주소
              ms.joinGroup(InetAddress.getByName("230.100.50.5"));
              //무한 반복해서 메시지 받기
              while(true) {
                   //바이트 배열 생성
                   byte [] b = new byte[512];
                   //데이터를 전송받을 패킷 만들기
                   DatagramPacket dp = new DatagramPacket(b, 512);
                   //데이터 받기 - 데이터가 올 때까지 대기
                   ms.receive(dp);
                   //바이트 배열을 문자열로 변환하기
                   String msg = new String(b);
                   //화면에 공백을 제거하고 출력
                   System.out.println(msg.trim());
              }
         } catch (Exception e) {
              System.out.println(e.getMessage());
         }
     }
}

Multicast 전송을 하는 클래스

//ms949
package multicast;
import java.util.Scanner;
public class MulticastSend {
     public static void main(String[] args) {
         try {
              //보내는 멀티캐스 소켓을 생성
              //포트번호가 없습니다.
              MulticastSocket ms = new MulticastSocket();
              //문자열을 입력받기 위한 스캐너 만들기
              Scanner sc = new Scanner(System.in);
              //닉네임 설정하기
              System.out.print("닉네임 입력: ");
              String nick = sc.nextLine();
              //계속 메시지 주고받기
              while(true) {
                   System.out.print("메시지(종료는 end):");
                   String msg = sc.nextLine();
                   if(msg.equals("end")) {
                       msg = nick + "님이 퇴장하셨습니다.";
                       //보내는 패킷 만들기 - 내용, 길이, 받을곳의 주소, 포트 번호
                       DatagramPacket dp = new DatagramPacket(msg.getBytes(),msg.getBytes().length,InetAddress.getByName("230.100.50.5"),9999);
                       //데이터 전송
                       ms.send(dp);
                       //소켓과 스캐너 닫기
                       ms.close();
                       sc.close();
                       break;
                       //if문에 break나 return이 있으면 끝난다는 거니까 else쓰지 않아도 됩니다.
                   }else {
                       //메시지 만들기
                       msg = nick + ":" + msg;
                       //보내는 패킷 만들기 - 내용, 길이, 받을곳의 주소, 포트 번호
                       DatagramPacket dp = new DatagramPacket(msg.getBytes(), msg.getBytes().length, InetAddress.getByName("230.100.50.5"), 9999);
                       //데이터 전송
                       ms.send(dp);
                   }
                   
              }
         } catch (Exception e) {
              System.out.println(e.getMessage());
         }
     }
}


{udp broadcast 전송}

- unicast 나 multicast는 특정한 컴퓨터 IP주소를 이용해서 데이터를 전송하는데 반해서 broadcast는 broadcast 주소를 이용해서 데이터를 전송하면 그 broadcast 영역 내에 있는 장비가 데이터를 전송받을 수 있는 방식입니다.

연산방식까지 써가면서 NETWOKR ID나 BROADCAST ID를 찾을 필요는 없다.
NETWOKR ID 는 말그대로 어떤 네트워크대역의 간판이되는 이름표같은 IP.
192.168.0.252 255.255.255.0 인경우
NETWOKR ID 가장 첫번째 IP인 192.168.0.0 이 됩니다.
BROADCAST ID 는 반대로 맨 마지막이 되는 IP.
위처럼 동일한 IP인 경우 BROADCAST ID 192.168.0.255 가 됩니다.





http://data.go.kr/
https://developers.kakao.com/
네이버, 카카오 developer 사이트 가입해서 api 뭐가 있는지 살펴 보기




{URL통신}

- 웹 주소를 이용해서 데이터를 다운로드 받는 통신

1. 필요한 클래스

1) URL로 인코딩 하기  위한 클래스의 메소드

- 인코딩을 위한 메소드 : URLEncoder.encode(String url, String charset) - url을 chartset으로 인코딩해서 리턴해주는 메소드입니다.


- 디코딩을 위한 메소드 : URLDecoder.decode(String url, String charset) - url을 charset으로 디코딩해서 리턴해주는 메소드입니다.


2. URL 클래스

- 주소와 관련된 클래스

- 다운로드 받을 URL을 만들어주는 클래스

- new URL(String 다운로드 받을 주소) : 잘못 된 주소를 설정하면 예외가 발생합니다.

- 예외처리를 반드시해주어야 합니다.


3. URLConnection 클래스

- URL을 이용해서 데이터를 주고 받을 수 있는 클래스

- URL 인스턴스의 openConnection 이라는 메소드를 호출해서 만드는데 HttpURLConnection 이나 HttpsURLConnection 자료형으로 형 변환해서 사용합니다.

- connectTimeout(접속 시도 시간 - 1/1000초 단위로 설정), useCache(이전에 다운로드 받은 데이터를 사용할지 여부를 boolean으로 설정) 옵션을 설정

- 데이터를 가져오기 위해서는 스트림을 생성해야 하는데 getInputStream()을 호출하면 데이터를 읽어올 수 있는 스트림을 리턴하는데, 이 스트림을 가지고 필요한 스트림을 생성해서 사용해야 합니다.

- 문자열일 때는 BufferedReader(new InputStreamReader(?.getInputStream()))으로 BufferedReader객체를 만들어서 읽어야 하고 일반 파일일 때는 BufferedInputStream(?.getInputStream()))으로 BufferedInputStream 객체를 만들어서 읽어야 합니다.


 파일- 통신

 스트림 생성

 바이트 스트림

(바이트 단위 - 텍스트 파일을 제외한 모든 자료)

 캐릭터 스트림

(텍스트 파일)

ObjectInputStream

ObjectOutputStream

파일을 읽고 출력 시키기 위한

 FileReader

FileWriter 

 FileInputStream

 FileOutputStream

 ↓

 ↓

 

 

 버퍼를 하기 위한

 BufferedReader

 PrintWriter

 BufferedInputStream

 PrintStream



4. Thread 클래스

- 네트워크를 사용하는 로직은 시간이 얼마나 걸릴지 알 수 없고 느린 작업이기 때문에 스레드를 이용하지 않으면 프로그램이 얼어버리는 효과가 나타날 수 있으므로 스레드를 이용해서 작업을 하도록 하고 작업 중 이라는 것을 계속 표시해주는 것이 좋습니다.

- iOS 나 Android에서는 이러한 작업을 하지 않으면 동작하지 않거나 마켓에서 reject 됩니다.

- 상속받는 클래스를 이용해서 만들기






class ? extends Thread{
public void run(){
스레드로 수행할 내용;
}
}
?변수명 = new ?();
변수명.start();




- 상속받는 클래스를 이용하지 않고 만들기

Thread 변수명 = new Thread(){

public void run(){

스레드로 수행할 내용;

}

};

변수명.start();

=>더조은 메인 페이지의 html 가져오기
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;


public class URLTextDownload {

public static void main(String[] args) {
try {
//1. 다운로드 받을 주소 만들기
String addr = "http://www.tjoeun.co.kr/";
//한글이 포함된 경우라면 URLEncoder.encode 메소드를
//이용해서 한글을 인코딩합니다.
//2. 주소를 가지고 URL 객체를 생성
URL url = new URL(addr);
//3. URL 연결 객체를 생성합니다.
HttpURLConnection con = 
(HttpURLConnection)url.openConnection();
//4. 옵션을 설정합니다.
//연결이 안되면 30초까지 시도
con.setConnectTimeout(30000);
//이전에 받은 데이터가 있어도 사용하지 않도록 설정
con.setUseCaches(false);
//5.다운로드 받을 스트림 생성
BufferedReader br = 
new BufferedReader(
new InputStreamReader(
con.getInputStream(), "EUC-KR") );
//6.데이터를 읽어서 String으로 만들기
//문자열을 복사하지 않고 편집할 수 있는 클래스의 객체 만들기
StringBuilder sb = new StringBuilder();
while(true) {
//한 줄의 문자열을 읽기
String line = br.readLine();
//읽은 게 없으면 읽기 중단
if(line == null) {
break;
}
//읽은 데이터가 있으면 sb에 추가
sb.append(line + "\n");
}
//읽은 데이터를 String으로 변환
String html = sb.toString();
//화면에 출력
System.out.println(html);
//7.사용한 객체 정리
br.close();
con.disconnect();
}catch(Exception e) {
System.out.println(e.getMessage());
}

}

}


이미지 파일을 다운로드 받아서 로컬 컴퓨터에 저장하기
파일을 다운로드 받아서 저장할 대는 파일의 존재여부를 확인해서 존재하는 경우는 다운로드 받지 않고 없는 경우에만 다운로드 받는 것이 좋습니다.
파일이 업데이트 되는 경우라면 최후 수정 시간을 확인해서 다운로드 합니다.
파일을 읽을 대는 버퍼드리더 대신에 퍼버드 인풋 스트림 객체를 만들어서 데이터를 바이트 단위로 읽어서 기록하면 됩니다.


http://www.onlifezone.com/files/attach/images/962811/376/321/005/2.jpg 의 파일을 다운로드 받아서 2.jpg 파일로 저장하기


C:\Users\503A5\Documents 디렉토리에 저장하기


import java.io.BufferedInputStream;
import java.io.File;
import java.io.PrintStream;
import java.net.URL;

public class URLFileDownload {

public static void main(String[] args) {
try {
//다운로드 받을 주소 만들기
String addr = 
//addr에서 마지막 / 이후의 문자열을 가져오기
//마지막 /의 위치를 찾습니다.
int idx = addr.lastIndexOf("/");
//addr에서 idx+1 번째 글자부터 가져오기
String filename = addr.substring(idx + 1);
//System.out.println(filename);
//filename을 이용해서 저장할 파일 경로 만들기
String filepath = 
"C:\\Users\\503A5\\Documents\\" + filename;
//파일이 존재하는지 확인
if((new File(filepath)).exists()) {
System.out.println("이미 파일이 존재합니다.");
}else {
//System.out.println("파일이 존재하지 않습니다.");
//스레드 객체 생성
Thread th = new Thread() {
public void run() {
try {
//다운로드 받을 URL 만들기
URL url = new URL(addr);
//연결 객체 생성
HttpURLConnection con = 
(HttpURLConnection)url.openConnection();
//옵션 설정
con.setConnectTimeout(20000);
con.setUseCaches(false);
//바이트 단위로 다운로드 받기 위한 스트림 생성
BufferedInputStream bis = 
new BufferedInputStream(con.getInputStream());
//다운로드 받은 내용을 기록할 스트림
PrintStream ps = new PrintStream(filepath);
while(true) {
//512 바이트 단위로 데이터 읽기
byte [] b = new byte[512];
int r = bis.read(b);
//읽은 데이터가 없으면 읽기 중단
if(r <= 0) {
break;
}
//읽은 데이터를 ps를 이용해서 기록하기
ps.write(b, 0, r);
}
//전부 기록했으면 정리
ps.close();
bis.close();
con.disconnect();
}catch(Exception e) {
System.out.println(e.getMessage());
}
}
};
//스레드 시작
th.start();
}
}catch(Exception e) {
System.out.println(e.getMessage());
}

}

}



'JAVA 공책 > 수업 메모' 카테고리의 다른 글

URL  (0) 2018.07.24
MulticastSoket22  (0) 2018.07.24
조건문&반복문  (0) 2018.07.23
네트워크  (0) 2018.07.23
Map추가 & PrintWriter & Serializable : 복습 꼭 필요!  (0) 2018.07.23