티스토리 뷰

IT/JAVA

13. Java 스트림과 병렬처리

a-toz 2017. 11. 9. 19:16

**PrintWriter

=>문자 단위로 기록할 수 있는 스트림

=>버퍼를 사용하기 때문에 입출력 횟수를 줄여서 효율적으로 기록을 하는 스트림


1.생성자

PrintWriter(String 파일경로) : 파일에 기록하는 경우

PrintWriter(File 객체)

PrintWriter(OutputStream 객체) : 네트워크에 이용하는 경우


2.기록하는 메소드

print(문자열)

printf(서식, 데이터)

println(문자열)


3.닫아주는 메소드

close()


ex)문자열을 파일에 기록하고 읽기

package io;


import java.io.BufferedReader;

import java.io.FileReader;

import java.io.PrintWriter;


public class Main1 {


public static void main(String[] args) {

//문자열을 파일에 기록하고 읽기

try{

//문자열을 파일에 기록하기 위한 객체를 생성

PrintWriter pw = 

new PrintWriter("c:\\java\\print.txt");

//스트림에 내용을 기록

pw.println("파일에 기록을 합니다.");

//스트림 닫기

pw.close();

}

catch(Exception e){

System.out.println(e.getMessage());

e.printStackTrace();

}

//위에서 작성한 내용을 읽기

try{

//문자열을 읽기 위한 스트림을 생성

BufferedReader br = 

new BufferedReader(

new FileReader("c:\\java\\print.txt"));

//파일의 모든 내용 읽기

while(true){

//한 줄의 문자열 읽기

String line = br.readLine();

//읽은 내용을 없으면 반복문 종료

if(line == null)

break;

//읽은 내용이 있을 때는 출력

System.out.println(line);

}

br.close();

}

catch(Exception e){

System.out.println(e.getMessage());

e.printStackTrace();

}


}


}


**Comparable(비교 가능), Runnable(스레드)


**Serializable

=>직렬화: 객체 단위로 스트림을 통해서 전송하는 것

=>java에서는 class가 Serializable 인터페이스를 implements 하면 객체 단위로 데이터를 전송할 수 있습니다.

=>객체 단위로 파일에 기록하거나 네트워크를 통해서 전송하면 동일한 클래스가 존재하지 않으면 내용을 파악할 수 없습니다.

=>응용프로그램을 만들 때 데이터를 저장하는 용도로 많이 사용

=>Java에서는 Serializable 인터페이스를 implements 한 객체를 전송할 때는 ObjectInputStream 과 ObjectOutputStream 클래스를 이용


ex)객체 직렬화

1.데이터를 표현할 클래스 - Data.java

package io;


import java.io.Serializable;


public class Data implements Serializable {

private int num;

private String name;

public int getNum() {

return num;

}

public void setNum(int num) {

this.num = num;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

@Override

public String toString() {

return "Data [num=" + num + ", name=" + name + "]";

}

}


2.데이터를 기록하기 - Main.java

package io;


import java.io.FileOutputStream;

import java.io.ObjectOutputStream;


public class Main2 {


public static void main(String[] args) {

try{

Data d1 = new Data();

d1.setNum(1);

d1.setName("이회영");

//객체 단위로 데이터를 저장하는 스트림 생성

ObjectOutputStream oos = 

new ObjectOutputStream(

new FileOutputStream(

"c:\\java\\oos.dat"));

//데이터 기록

oos.writeObject(d1);

oos.close();

}

catch(Exception e){

System.out.println(e.getMessage());

e.printStackTrace();

}


}


}


3.데이터를 읽어오기 - Main.java

package io;


import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.ObjectInputStream;

import java.io.ObjectOutputStream;


public class Main2 {


public static void main(String[] args) {

try{

//객체 단위로 데이터를 읽어오는 스트림 생성

ObjectInputStream ois = 

new ObjectInputStream(

new FileInputStream(

"c:\\java\\oos.dat"));

//데이터 읽어오기

//readObject 메소드로 읽어오면 object 타입으로 리턴되므로

//반드시 원래의 자료형으로 변환해서 읽어야 합니다.

Data data =(Data)ois.readObject();

//읽어온 데이터 출력

System.out.println(data);

//스트림 닫기

ois.close();

}

catch(Exception e){

System.out.println(e.getMessage());

e.printStackTrace();

}


}


}


** 네트워크 명령

1.자기 컴퓨터 IP 알아내기

ipconfig

ipconfig /all


2.상대방과 통신이 가능한지 알아내는 명령

ping 상대방아이피 또는 도메인


3.내 컴퓨터가 사용 중인 포트번호 확인

netstat -ano


**InetAddress

=>컴퓨터의 IP 주소정보를 저장하는 클래스

=>생성자를 이용해서 객체를 생성하지 않고 static 메소드를 이용해서 객체를 생성합니다.

ex)www.daum.net의 IP 주소 정보를 확인

package net;


import java.net.InetAddress;


public class Main1 {


public static void main(String[] args) {

try{

//www.daum.net의 IP 주소 정보를 가져오기

InetAddress [] addr = 

InetAddress.getAllByName("www.qualcomm.co.kr");

//배열의 모든 요소 접근

for(InetAddress ad : addr){

System.out.println(ad);

}

}

catch(Exception e){

System.out.println(e.getMessage());

e.printStackTrace();

}


}


}


**TCP 통신

=>연결 지향 형 통신

=>보내는 곳과 받는 곳이 연결된 상태에서 데이터를 주고 받는 방식

=>항상 연결이 되어있어야 하기 때문에 트래픽이 증가합니다.

=>신뢰성이 높고 안정성이 있습니다.

=>중요한 메시지 전송에는 TCP 방식을 사용합니다.


1.TCP 방식에서의 클라이언트 소켓(연결하는 쪽) 생성

new Socket(연결할 서버의 IP 정보, 포트번호)


2.데이터를 주고받기 위한 스트림 가져오기

1)읽기 위한 스트림

소켓.getInputStream()


2)전송하기 위한 스트림

소켓.getOutputStream()


3.소켓 닫기

소켓.close()


4.TCP 통신 과정

1)접속할 곳의 IP 주소를 생성


2)Socket 생성자에 IP 주소와 포트번호를 대입해서 연결


3)스트림을 생성


4)스트림을 이용해서 데이터를 송수신


5)스크림과 소켓을 닫기


ex)www.daum.net 의 80번 포트에 접속해서 데이터 가져오기

=>웹 브라우저의 기본적인 데이터 가져오는 방법

package net;


import java.io.BufferedReader;

import java.io.InputStreamReader;

import java.io.PrintWriter;

import java.net.InetAddress;

import java.net.Socket;


public class Main2 {

public static void main(String [] args){

try{

//www.daum.net 의 IP 정보를 가져오기

InetAddress addr = 

InetAddress.getByName("www.daum.net");

//daum의 80번 포트와 통신할 수 있는 소켓을 생성

Socket socket = 

new Socket(addr, 80);

//상대방과 문자 단위로 데이터를 주고받을 수 있는

//스트림을 생성

BufferedReader br = 

new BufferedReader(

new InputStreamReader(

socket.getInputStream()));

PrintWriter pw = 

new PrintWriter(

socket.getOutputStream());

//메시지 전송

pw.println("GET http://www.daum.net");

pw.flush();

//메시지 읽기

while(true){

String line = br.readLine();

if(line == null)

break;

System.out.println(line);

}

//사용한 스트림과 소켓 닫기

br.close();

pw.close();

socket.close();

}

catch(Exception e){

System.out.println(e.getMessage());

e.printStackTrace();

}

}

}


5.ServerSocket

=>클라이언트 요청을 받을 수 있는 소켓

1)객체 생성

new ServerSocket(포트번호)

new ServerSocket(포트번호, 동시에 접속할 수 있는 개수)


2)사용하는 메소드

클라이언트의 접속을 대기하는 메소드 :  Socket accept() - 클라이언트의 접속이 올 때 까지 대기상태가 되고 클라이언트가 접속하면 클라이언트와 통신할 수 있는 Socket을 리턴


닫는 메소드 :  close()


ex)TCP 통신을 이용해서 한 줄 메시지를 주고 받는 서버와 클라이언트

서버

package net;


import java.io.BufferedReader;

import java.io.InputStreamReader;

import java.io.PrintWriter;

import java.net.ServerSocket;

import java.net.Socket;


public class TcpServerMain {


public static void main(String[] args) {

try{

//9000번 포트로 클라이언트의 요청을 받아들이도록 

//서버 소켓을 생성

ServerSocket ss = 

new ServerSocket(9000);

System.out.println("서버 대기 중");

//클라이언트 접속 대기

Socket socket = ss.accept();

//클라이언트와 통신하기 위한 스트림 생성

PrintWriter pw = 

new PrintWriter(socket.getOutputStream());

BufferedReader br = 

new BufferedReader(

new InputStreamReader(

socket.getInputStream()));

//데이터 읽기

String msg = br.readLine();

System.out.println("클라이언트가 보낸 메시지:" + msg);

pw.println("서버가 보내는 메시지");

pw.flush();

//작업이 끝나면 정리

pw.close();

br.close();

socket.close();

ss.close();

}

catch(Exception e){

}


}


}




클라이언트

import java.io.BufferedReader;

import java.io.InputStreamReader;

import java.io.PrintWriter;

import java.net.InetAddress;

import java.net.Socket;


public class TcpClientMain {


public static void main(String[] args) {

try{

InetAddress addr = 

InetAddress.getByName("127.0.0.1");

Socket socket = new Socket(addr, 9000);

PrintWriter pw = 

new PrintWriter(socket.getOutputStream());

BufferedReader br = 

new BufferedReader(

new InputStreamReader(

socket.getInputStream()));

pw.println("Hello Server");

pw.flush();

String msg = br.readLine();

System.out.println(msg);

pw.close();

br.close();

socket.close();

}

catch(Exception e){}


}


}


**UDP

=>비연결형 전송의 프로토콜

=>데이터그램 전송방식이라고도 합니다.

1.데이터를 주고받기 위한 소켓 클래스 - DatagramSocket

1)생성자

DatagramSocket(int port) : 연결 당하는 쪽

DatagramSocket(int port, InetAddress addr) :  연결하는 쪽


2)메소드

close(): 닫기

receive(DatagramPacket dp) : 데이터 전송을 위한 메소드

send(DatagramPacket dp) : 데이터를 받기 위한 메소드


2.전송되는 데이터 클래스 - DatagramPacket

=>생성자

DatagramPacket(byte[] buf, int length): buf에 length 만큼 전송받기 위한 생성자

DatagramPacket(byte[] buf, int length, InetAddress addr, int port): 전송하기 위한 생성자 


ex)UDP unicast 통신

받는쪽

import java.net.DatagramPacket;

import java.net.DatagramSocket;


public class UDPServer {


public static void main(String[] args) {

try{

DatagramSocket ds = 

new DatagramSocket(7777);

while(true){

byte [] data = new byte[65536];

DatagramPacket dp = 

new DatagramPacket(data, 65536);

ds.receive(dp);

String msg = new String(dp.getData());

msg = msg.trim();

System.out.println("message:" + msg);

}

}

catch(Exception e){

System.out.println(e.getMessage());

}

}


}


보내는 쪽

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 ds = new DatagramSocket();

Scanner sc = new Scanner(System.in);

while(true){

System.out.print("send message:");

String msg = sc.nextLine();

InetAddress addr = 

InetAddress.getByName("127.0.0.1");

DatagramPacket dp = 

new DatagramPacket(msg.getBytes(),

msg.getBytes().length,

addr, 7777);

ds.send(dp);

}

}

catch(Exception e){

System.out.println(e.getMessage());

}


}


}


**Multicast 전송

=>동일한 그룹에 속한 모든 소켓 과 통신

=>약속된 주소에 데이터를 전송하고 그 전송된 데이터를 읽어내는 방식

=>이 때 약속된 주소는 D 클래스 주소(224.0.0. - 239.255.255.255)

=>소켓을 만들 때는 MulticastSocket을 이용

=>화상회의 처럼 여러 명이 동일한 데이터를 공유해야 하는 경우에 사용


1.Multicast 서버 만들기 : 데이터를 받는 프로그램

'IT > JAVA' 카테고리의 다른 글

12. Java 스트림과 병렬처리  (0) 2017.11.09
11. Java AWT  (0) 2017.11.09
10. Java Thread  (0) 2017.11.09
9. Java Map,Set  (0) 2017.11.09
8. Java 유용한 API  (0) 2017.11.09
댓글