보조 스트릠 : 실제 읽고 쓰는 스트림이 아닌 보조 기능을 제공하는 스트림
FilterInputStream , FilterOutputStream : 보조스트림의 상위 클래스(추상 클래스)
위의 두 클래스는 추상클래스이기 때문에생성자의 매개변수로 또 다른 스트림을 가짐
이를 데코레이터 패턴 Decorator Pattern으로 구현
자바의 스트림은 데코레이터 패턴이다.
데코레이터 패턴
: 객체의 결합을 통해 기능을 동적으로 유연하게 확장 할 수 있게 해주는 패턴
즉, 기본 기능에 추가할 수 있는 기능의 종류가 많은 경우에 각 추가 기능을 Decorator 클래스로 정의한 후 필요한 Decorator 객체를 조 합함으로써 추가 기능의 조합을 설계하는 방식
기존 기능에 addon 하는 방식으로 추가기능을 해주는 방식
Component : 실제 객체
ConcreteComponent : 기본 기능 구현 클래스
Decorator : 많은 수가 존재하는 구체적인 데코레이터의 공통 기능을 제공
그 하위 클래스 : 기본 기능에 추가되는 개별적인 기능을 가진 클래스
상위 클래스 생성자
1. protected FilterInputStream(InputStream in) : 생성자의 매개변수로 InputStream을 받음
2. public FilterOutputStream(OutputStream out) : 생성자의 매개변수로 OutputStream을 받음
[바이트 단위 파일 입력 스트림(기반 스트림)] + [문자로 변환 기능 추가(보조 스트림)] + [버퍼링 기능 추가(보조 스트림)]
(컴포넌트) (데코레이터) (데코레이터)
InputStreamReader 와 OutputStreamWriter
: 읽어들일 때 바이트를 문자로
: 쓸 때 바이트를 문자로
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
public class InputStreamReaderTest {
public static void main(String args[]) {
// 한글의 경우 깨짐
//try(FileInputStream fi = new FileInputStream("data.txt")){
// FileReader의 경우 문자스트림으로 깨지지 않음
//FileReader fr = new FileReader("data.txt");
// 보조스트림 감싸서 사용
// FileInputStream인 바이트로 읽어들인 것을 보조스트림으로 감싸서 한글을 깨지지 않게 함
// 보조스트림이 닫히면 기반스트림도 닫히므로 별도의 CLOSE()할 필요없다
try(InputStreamReader is = new InputStreamReader(new FileInputStream(("data.txt")))){
int i;
//while((i=fi.read()) != -1) {
while((i=is.read()) != -1) {
System.out.print((char)i);
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
|
cs |
BufferedInputStream 과 BufferedOutputStream
: 약 8k의 배열이 제공되어 입출력이 빠르게 하는 기능이 제공되는 보조스트림
BufferedReader : 문자를 읽어들일 때 버퍼기능(8k의 배열을 제공)을 사용하여 빠르게 읽음
BufferedWriter : 문자를 쓸 때 버퍼기능을 사용하여 빠르게 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
|
public class FileCopyTest {
public static void main(String args[]) {
// 복사 시간
long millse = 0;
// a 파일 입력스트림, acopy를 출력 스트림 열기
//try(FileInputStream fi = new FileInputStream("a.zip");
// FileOutputStream fo = new FileOutputStream("acopy.zip"))
// 버퍼스트림 사용으로 속도 향상
try(BufferedInputStream bi = new BufferedInputStream(new FileInputStream("data.txt"));
BufferedOutputStream bo = new BufferedOutputStream(new FileOutputStream("datacopy.txt"))){
millse = System.currentTimeMillis(); // 현재 시간을 밀리초로
int i;
//while( (i = fi.read()) != -1 ) {
while( (i = bi.read()) != -1 ) {
//fo.write(i);
bo.write(i);
}
millse = System.currentTimeMillis() - millse;
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
}
System.out.println(millse + "밀리초");
// 소켓 사용 방법
// Socket socket = new Socket();
// try {
// // 버퍼스트림((문자스트림(소켓바이트스트림))
// 바이트 -> 문자 -> 속도향
// BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
// // readLin()는 한줄 씩 읽어드리는 bufferreader의 메소드
// br.readLine();
// } catch (IOException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
}
}
|
cs |
소켓 Socket
: 프로세스간의 통신에 사용되는 양쪽 끝단을 의미
자바에서 java.net패키지를 통해 지원
소켓 통신에 사용되는 프로토콜에 따라 다른 종류의 소켓을 구현하여 제공
TCP Transmission Control Protocol
: 인터넷 상에서 데이터를 메세지 형태로 보내기 위해 IP와 함께 사용하는 프로토콜
IP가 데이터의 배달을 처리한다면 TCP는 패킷을 추적 및 관리한다.
연속성보다 신뢰성있는 전송이 중요할 때에 사용하는 프로토콜로 파일전송과 같은 경우에 사용
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
|
package com.java.tcp;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.Date;
public class TCPServer {
public static void main(String[] args) {
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(80);
System.out.println(getTime() + "서버가 준비되었습니다.");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
while (true) {
try {
System.out.println(getTime() + "연결요청을 기다리는중 . . .");
//서버 소켓은 클라이언트의 연결요청이 올때까지 실행을 멈추고 계속 기다린다.
//클라이언트의 연결요청이 들어오면 클라이언트 소켓과 통신할 새로운 소켓을 생성한다.
Socket socket = serverSocket.accept();
System.out.println(getTime() + socket.getInetAddress()
+ "로 부터 연결 요청이 들어왔습니다.");
//소켓의 출력스트림을 얻는다.
OutputStream out = socket.getOutputStream();
DataOutputStream dos = new DataOutputStream(out);
//원격 소켓에 데이터를 보낸다.
dos.writeUTF("test 메세지 입니다");
System.out.println(getTime() + "데이터를 전송했습니다.");
//스트림과 소켓을 닫아준다.
dos.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//현재 시간을 문자열로 반환하는 함수
private static String getTime() {
SimpleDateFormat f = new SimpleDateFormat("[hh.mm.ss]");
return f.format(new Date());
}
}
|
cs |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
public class TCPClient {
public static void main(String[] args) {
try {
String serverIp = "xxx.xxx.x.xx"; // 서버 pc IP로 변경
System.out.println("서버에 연결 중 입니다. 서버 IP : " + serverIp);
//소켓을 생성하여 연결을 요청.
Socket socket = new Socket(serverIp, 80);
//소켓의 입력 스트림을 얻는다.
InputStream in = socket.getInputStream();
DataInputStream dis = new DataInputStream(in);
//소켓으로 받은 데이터 출력.
System.out.println("받은 메세지 : " + dis.readUTF());
System.out.println("연결을 종료합니다 .");
//스트림과 소켓을 닫는다.
dis.close();
socket.close();
System.out.println("연결이 종료되었습니다.");
} catch (ConnectException ce) {
ce.printStackTrace();
} catch (IOException ie) {
ie.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
|
cs |
패킷 Packet
: 인터넷 내에서 데이터를 보내기 위한 경로배정(라우팅)을 효율적으로 하기 위해서 데이터를 여러 개의 조각들로 나누어 전송 하는데 이때, 이 조각을 패킷이라고 함
UDP User Datagram Protocol
: 데이터를 데이터그램 단위로 처리하는 프로토콜
데이터그램이란 독립적인 관계를 지니는 패킷
TCP와 달리 비연결형 프로토콜, 즉 연결을 위해 해당되는 논리적인 경로가 없는데, 각각의 패킷은 다른 경로로 전송되고, 각각의 패킷은 독립적인 관계를 지니게 되는데 이렇게 데이터를 서로 다른 경로로 독립적으로 처리하게 된다.
TCP보다 속도가 빠르며 네트워크 부하가 적다는 장점이 있어 연속성이 중요한 서비스인 실시간 서비스에 자주 사용됨.
1. 비연결 지향
2. 데이터를 전송할 때에 데이터가 잘 도착했는지 알아낼 방법이 없으며, 데이터를 보낸 순서대로 도착한다는 보장이 없음
3. TCP에 비해 빠름
4. java.net.DatagramPacket 클래스로 추상화
DatagramPacket클래스는 애클리케이션에서 주고 받을 데이터와 관련된 클래스이고, 실제 데이터의 전송을 책임짐
DatagramPacket클래스는 데이터를 송신하 기 위한 기능과 수신을 하기 위한 기능으로 분리
DataSocket클래스는 TCP 스트림 소켓과 달리 서버와 클라이언트 데이터 그램 소켓 사이에는 차이가 없으며, 모든 데이터그램 소켓 은 데이터그램을 전송할 뿐만 아니라 수신에서 사용함
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
public class UDPServer {
public UDPServer(int port) {
try {
// 1. UDP 통신인 DatagramSocket으로 객체 생성하여 포트지정
DatagramSocket ds = new DatagramSocket(port);
while (true) {
byte buffer[] = new byte[512];
// 2. 데이터를 받기위한 바이트 크기와 길이를 받는 생성자로 객체 생성
DatagramPacket dp = new DatagramPacket(buffer,buffer.length);
System.out.println("ready");
// 3. 데이터그램을 수신하기 위해 DatgramSocket객체를 사용하여 DatagramPacket에 받음
ds.receive(dp);
// 4. getData()를 사용하여 데이터를 바이트배열로 반환
String str = new String(dp.getData());
// 5. 바이트 배열을 String으로 형변환후 출력
System.out.println("수신된 데이터 : " + str);
// 6. 자바에서 IP주소를 표현할때 사용하는 클래스
// 7. DatagramPacket클래스의 getAddress()를 통해 목적지또는 출발지 주소를 반환
InetAddress ia = dp.getAddress();
// 8. 포트도 반환
port = dp.getPort();
System.out.println("client ip : " + ia + " , client port : " + port);
dp = new DatagramPacket(dp.getData(),dp.getData().length, ia,port);
ds.send(dp);
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
public static void main(String[] args) throws Exception {
// 3000 UDP Port 지정
new UDPServer(3000);
}
}
|
cs |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
public class UDPClient{
private String str;
private BufferedReader file;
private static int SERVERPORT=3000;
public UDPClient(String ip,int port){
try{
InetAddress ia = InetAddress.getByName(ip);
DatagramSocket ds = new DatagramSocket(port);
System.out.print("message : ");
file = new BufferedReader(new InputStreamReader(System.in));
str = file.readLine();
byte buffer[] = str.getBytes();
DatagramPacket dp = new DatagramPacket(
buffer,buffer.length,ia,SERVERPORT);
ds.send(dp);
buffer = new byte[512];
dp = new DatagramPacket(buffer,buffer.length);
ds.receive(dp);
System.out.println("server ip : "+dp.getAddress() + " , server port : "+dp.getPort());
System.out.println("수신된 데이터 : "+ new String(dp.getData()).trim());
}catch(IOException ioe){
ioe.printStackTrace();
}
}
public static void main(String[] args){
new UDPClient("localhost",2000);
}
}
|
cs |
DataInputStream 과 DataOutputStream
: 자료가 메모리에 저장된 상태 그대로 읽거나 쓰는 스트림 (보조스트림)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
public class DataStreamTest {
public static void main(String args[]) {
try(FileOutputStream fos = new FileOutputStream("data.txt");
DataOutputStream dos = new DataOutputStream(fos)){
dos.writeByte(100);
dos.writeChar('A');
dos.writeInt(19);
dos.writeFloat(3.14f);
dos.writeUTF("TEST");
}catch(Exception e) {
}
try(FileInputStream fis = new FileInputStream("data.txt");
DataInputStream dis = new DataInputStream(fis)){
System.out.println(dis.readByte());
System.out.println(dis.readChar());
System.out.println(dis.readInt());
System.out.println(dis.readFloat());
System.out.println(dis.readUTF());
}catch(Exception e) {
}
}
}
|
cs |
'OOP > Java' 카테고리의 다른 글
Thread (0) | 2022.05.29 |
---|---|
직렬화 (0) | 2022.05.29 |
문자 단위 스트림 (0) | 2022.05.22 |
바이트 단위 입출력 스트림 (0) | 2022.05.22 |
표준 입출력 스트림 (0) | 2022.05.22 |