파일입출력 - 문자열 출력
문자열은 객체 출력, 멀티바이트 출력, 싱글바이트 출력 모두 가능하다.
하지만 객체, 멀티바이트는 안쓴다 -> 싱글바이트 사용
싱글바이트
FileWriter를 사용한 문자열 출력
1. 버퍼의 크기를 변경할 수 있는가?
--> BufferedWriter 사용
2. 한줄단위 출력 또는 다른 유형의 데이터도 문자열로 출력?
--> PrintWriter 사용
package api.io.string;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
public class Test04 {
public static void main(String[] args) throws IOException {
File target = new File("sample", "string.txt");
FileWriter out = new FileWriter(target);
out.write("안녕 Java!");
out.write("\n");
out.write("안녕 Java!");
out.write("\n");
out.write("안녕 Java!");
out.write("\n");
int a = 100;
// out.write(a);
// out.write("100");
out.write(String.valueOf(a));
// out.flush();
out.close();
}
}
필요한 Writer들을 조합하여 사용
(System.out 도 PrintWriter 형태의 객체이다.)
package api.io.string;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
public class Test05 {
public static void main(String[] args) throws IOException {
File target = new File("Sample", "string.txt");
FileWriter out = new FileWriter(target);
BufferedWriter buffer = new BufferedWriter(out, 8192);// 외장버퍼
PrintWriter printer = new PrintWriter(buffer);// 출력도우미
// [프로그램] → printer → buffer → out → target → [string.txt]
// write가 아니라 print 계열의 명령으로 출력을 할 수 있도록 지원
printer.println("안녕 Java!");
printer.println("안녕 Java!");
printer.println("안녕 Java!");
int a = 100;
printer.println(a);
// printer.flush();
printer.close();
}
}
안녕 Java!
안녕 Java!
안녕 Java!
100
Q. 사용자에게 문자열을 지속적으로 입력받아 `sample/user.txt` 파일에 저장하는 프로그램을 구현
사용자가 `종료`라고 입력하면 프로그램을 종료하도록 처리
package api.io.string;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Scanner;
public class Test06_1 {
public static void main(String[] args) throws IOException {
Scanner sc = new Scanner(System.in);
File target = new File("sample", "user.txt");
FileWriter out = new FileWriter(target);
BufferedWriter buffer = new BufferedWriter(out);
PrintWriter printer = new PrintWriter(buffer);
// [키보드] → System.in → sc → [프로그램] → printer → buffer → out → target → [user.kh]
while (true) {
System.out.print("입력 : ");
String line = sc.nextLine();
if (line.equals("종료"))
break;
printer.println(line);
printer.flush();
}
sc.close();
printer.close();
System.out.println("저장이 완료되었습니다");
}
}
입력 : 헬로우
입력 : hello
입력 : 1234
입력 : 종료
저장이 완료되었습니다
헬로우
hello
1234
- 임시 파일 만드는법
package api.io.string;
import java.io.File;
import java.io.IOException;
public class Test06_2 {
public static void main(String[] args) throws IOException {
// 임시파일 생성
File dir = new File("sample");
File tempFile = File.createTempFile("temp-", ".txt", dir);
// 임시 파일은 예약 삭제를 설정
tempFile.deleteOnExit();
}
}
문자열 입력
글자 수를 정해서 입력받는것이 아니라 줄 단위로 입력받도록 도구를 조합
줄 단위라 함은 개행문자(\n)를 발견하기 전까지라고 볼 수 있다.
package api.io.string;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
public class Test08_1 {
public static void main(String[] args) throws IOException {
File target = new File("sample", "string.txt");
FileReader in = new FileReader(target);
BufferedReader buffer = new BufferedReader(in);
// BufferedReader에는 read() 말고 readLine() 이라는 명령이 있다.
// (주의) EOF == null 이다
while (true) {
String line = buffer.readLine();
if (line == null)
break;
System.out.println("line = " + line);
}
buffer.close();
}
}
line = 안녕 Java!
line = 안녕 Java!
line = 안녕 Java!
line = 100
네트워크 - 기본 개념 및 포트스캔
# 네트워크 프로그래밍
네트워크 연결이 되어 있다는 전제 하에 다른 대상과 데이터를 주고받는 프로그램을 구현하는 것
- 기반지식
- 네트워크 구성에 대한 이해(IP, Port, Protocol)
- 쓰레드(Thread)에 대한 이해
- 스트림(Stream)에 대한 이해
- 데이터의 종류
- 싱글바이트
- 멀티바이트
- 객체
- 문자열
## 통신 방식에 따른 구분
- 연결형 통신 : TCP
- 소켓(Socket) : 생성된 연결
- 클라이언트(Client) : 연결을 시도하는 주체
- 서버(Server) : 연결을 수락하는 주체
- IP : 연결 생성을 위한 네트워크상에서의 PC 식별정보
- Port : 연결 생성을 위한 PC 내에서의 프로그램 식별정보
- 비연결형 통신 : UDP
- 전송자(Sender) : 데이터를 보내는 주체
- 수신자(Receiver) : 데이터를 받는 주체
- 유니캐스트(Unicast) : 일대일 메세지 전송 방식
- 멀티캐스트(Multicast) : 특정 채널에 소속된 대상에게만 메세지를 보내는 방식(ex : 카톡 그룹채팅)
- 브로드캐스트(Broadcast) : 전체에게 메세지를 보내는 방식(ex : 공지사항, 방송)
Server
TCP 서버에서 필요한 코드를 분석
= 음식점과 같은 가게의 역할과 비슷하다.
= 가게 문을 열고 손님을 받을 준비를 해야 한다.
= 가게 문을 연다는 것은 프로그램을 구동시킨다는 것을 의미
= 프로그램은 구동되려면 반드시 포트를 설정해야 한다.
= 포트의 범위는 0 부터 65535 까지이다.
= (중요) 하나의 포트에는 하나의 프로그램만 구동할 수 있다.
내 컴퓨터에서 사용하는 포트 확인하는 프로그램(포트스캐너)
= 0부터 65535까지 다 열어보면 된다.
package api.net.tcp01;
import java.io.IOException;
import java.net.ServerSocket;
public class Server2 {
public static void main(String[] args) {
for (int i = 0; i <= 65535; i++) {
try {
ServerSocket server = new ServerSocket(i);
// System.out.println("사용 가능한 번호입니다");
} catch (IOException e) {
System.out.println("[" + i + "] 이미 사용중인 번호입니다");
}
}
}
}
네트워크 - 서버 준비코드
= 서버를 30000번(안쓰는포트) 포트에서 구동되도록 생성
= 사용자가 접속할 때까지 기다린 뒤 접속 정보를 socket 형태로 관리
= socket에는 다음 정보가 필요하다
1. 접속한 클라이언트의 공인IP주소
2. 접속한 클라이언트 프로그램의 Port번호
3. 서버의 Port번호
= 다 사용한 자원들을 정리
package api.net.tcp01;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class Server3 {
public static void main(String[] args) throws IOException {
// 서버를 30000번 포트에서 구동되도록 생성
ServerSocket server = new ServerSocket(30000);
System.out.println("서버가 구동되었습니다");
// 사용자가 접속할 때까지 기다린 뒤 접속 정보를 socket 형태로 관리
Socket socket = server.accept();
System.out.println("서버에 클라이언트가 접속했습니다");
// socket에는 다음 정보가 필요하다
// 1. 접속한 클라이언트의 공인IP주소
// 2.접속한 클라이언트 프로그램의 Port번호
// 3. 서버의 Port번호
System.out.println("소켓 정보 : " + socket.toString());
// 데이터를 주고받는 코드
// 다 사용한 자원들을 정리
socket.close();// 사용자 1명과의 연결을 종료
System.out.println("사용자와의 연결을 종료하였습니다");
server.close();// 서버를 중지
System.out.println("서버를 중지하였습니다");
}
}
네트워크 - 클라이언트 소켓 생성
Client
TCP 클라이언트에서 필요한코드
=클라이언트는 음식점에 비유하면 손님과 같은 역할을 수행
=손님은 가게가 문을 열면 전화를 걸어서 음식을 주문할 수 있다.
= 전화를 거는 행위는 소켓을 생성한다고 볼 수 있다.
= 전화를 걸기 위해서는전화번호가 필요한 것처럼 소켓을 생성하려면 대상 프로그램의 위치정보가 필요하다
= IPv4정보와 Port정보가 필요하다.
package api.net.tcp01;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
public class Client {
public static void main(String[] args) {
// Socket Socket = new Socket(IP주소, Port번호);
try {
Socket socket = new Socket("ip", 30000);// 127.0.0.1은 IP계의 this
// Plan A : 정상적으로 연결이 수행된 경우
System.out.println("연결 성공했습니다");
} catch (Exception e) {
// Plan B : 어떠한 원인에 의해 연결이 수행되지 않은 경우
System.out.println("연결이 실패했습니다");
e.printStackTrace();
}
}
}
네트워크 - 클라이언트 준비코드
package api.net.tcp01;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
public class Client2 {
public static void main(String[] args) throws UnknownHostException, IOException {
Socket socket = new Socket("ip", 30000);
System.out.println("연결 성공했습니다");
System.out.println("소켓 정보 : "+socket);
//데이터를 주고받는 코드
//연결 종료
socket.close();
System.out.println("서버와의 연결이 종료되었습니다");
}
}
네트워크 - 바이트 전송 예제
Client에게 byte 5개를 전달하는 코드
= socket.getOutputStream()을 활용하여 출력
package api.net.tcp02;
import java.io.IOException;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
public static void main(String[] args) throws IOException {
ServerSocket server = new ServerSocket(30000);
Socket socket = server.accept();
OutputStream out = socket.getOutputStream();
out.write(104);
out.write(101);
out.write(108);
out.write(108);
out.write(111);
socket.close();
server.close();
}
}
Server에서 전송되는 byte 5개를 수신하는 코드
= socket.getInputStream()을 활용하여 입력
package api.net.tcp02;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import java.net.UnknownHostException;
public class Client {
public static void main(String[] args) throws UnknownHostException, IOException {
// Socket socket= new Socket("127.0.0.1", 30000);
Socket socket = new Socket("localhost", 30000);
InputStream in = socket.getInputStream();
int a = in.read();
int b = in.read();
int c = in.read();
int d = in.read();
int e = in.read();
socket.close();
System.out.println(a);
System.out.println(b);
System.out.println(c);
System.out.println(d);
System.out.println(e);
}
}
104
101
108
108
111
Q. 서버에서는 특정 파일을 접속자에게 배포하도록 구성되어 있습니다.
- 서버의 주소 : ip
- 서버의 포트 : 30000
`Client` 클래스를 만든 뒤, 서버에 접속하여 배포하는 파일을 받아 `lion.gif`라는 이름으로 저장하도록 프로그램을 구현
package api.net.tcp03;
import java.io.File;
import java.io.FileInputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
public static void main(String[] args) {
// 파일을 먼저 다 불러와놓고 사용자 접속 시 전송하도록 구현
// = 접속할 때마다 불러오는것보다 성능이 탁월하게 좋음
File target = new File("image", "lion.gif");
byte[] buffer = new byte[(int) target.length()];
try (FileInputStream in = new FileInputStream(target);) {
in.read(buffer);
} catch (Exception e) {
System.err.println("이미지 로딩 실패");
System.exit(-1);
}
while (true) {
try (ServerSocket server = new ServerSocket(30000);) {
System.out.println("서버 구동 시작");
while (true) {
try (Socket socket = server.accept();) {
System.out.println("사용자 접속 : " + socket.getInetAddress().getHostAddress());
socket.getOutputStream().write(buffer);
System.out.println("--> 이미지 전송 완료");
}
}
} catch (Exception e) {
// e.printStackTrace();
System.err.println("--> 에러 발생");
}
}
}
}
package api.net.tcp03;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
public class Client3 {
public static void main(String[] args) throws UnknownHostException, IOException {
// 서버에 접속해서 전송되는 이미지를 다운로드받아 `download/lion.gif`로 저장
// = TCP 연결
// = 파일 출력(싱글바이트)
Socket socket = new Socket("ip", 30000);
// 파일을 내려받는 코드
// = 버퍼의 크기를 8192 byte로 정하고 수신하여 저장
InputStream in = socket.getInputStream();
BufferedInputStream buffer = new BufferedInputStream(in, 8192);
byte[] data = new byte[8192];
File dir = new File("download");
dir.mkdirs();
File target = new File(dir, "lion.gif");
OutputStream out = new FileOutputStream(target);
while (true) {
int size = buffer.read(data);
if (size == -1)
break;
// 파일 출력 코드
// System.out.println("size = " + size);
out.write(data, 0, size);
}
socket.close();
out.close();
}
}
- 과제
클라이언트가 접속하면 접속한 클라이언트에게 이번주 로또번호 6개를 전송하는 서버를 구현
클라이언트는 서버가 전송하는 로또번호를 받아서 화면에 출력하도록 구현
접속할 때마다 다른 번호가 오도록 프로그래밍 하세요
package api.net.tcp04;
import java.io.IOException;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Random;
import java.util.Set;
import java.util.TreeSet;
public class Server {
public static void main(String[] args) throws IOException {
ServerSocket server = new ServerSocket(30000);
System.out.println("로또 프로그램 시작");
while (true) {
Socket socket = server.accept();
System.out.println("로또 번호 전송 완료");
OutputStream out = socket.getOutputStream();
Random r = new Random();
Set<Integer> lotto = new TreeSet<>();
while (lotto.size() < 6) {
int number = r.nextInt(45) + 1;
lotto.add(number);
}
for (int number : lotto) {
out.write(number);
}
socket.close();
}
}
}
package api.net.tcp04;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import java.util.Set;
import java.util.TreeSet;
public class Client {
public static void main(String[] args) throws IOException {
Socket socket = new Socket("localhost", 30000);
InputStream in = socket.getInputStream();
Set<Integer> lotto = new TreeSet<>();
while (true) {
int number = in.read();
if (number == -1)
break;
lotto.add(number);
}
System.out.println("이번주 로또번호는?-->" + lotto);
socket.close();
in.close();
}
}
'Java 웹 개발' 카테고리의 다른 글
21.09.23 - 웹 개발 입문 29일차 (0) | 2021.09.23 |
---|---|
21.09.17 - 웹 개발 입문 28일차 (0) | 2021.09.17 |
21.09.15 - 웹 개발 입문 26일차 (0) | 2021.09.15 |
21.09.14 - 웹 개발 입문 25일차 (0) | 2021.09.14 |
21.09.13 - 웹 개발 입문 24일차 (0) | 2021.09.14 |