실행방법
severFile 디버그(벌레 아이콘) 실행
ClientFile 실행 (run Client)
severFile 실행 (resume) 실행 (Navigation 밑에 있는 아이콘)
package ch02;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
public class ClientFile {
public static void main(String[] args) {
// 클라이언트 측 준비물
// 1. 서버측 IP 주소와 포트 번호가 필요하다.
// 2. 서버측 소켓과 연결될 소켓이 필요하다.
Socket socket = null;
try {
socket = new Socket("localhost", 5001);
PrintWriter writer = new PrintWriter(socket.getOutputStream(), true);
writer.println("안녕 반가워 ~ ");
// writer.flush();
// new PrintWriter(socket.getOutputStream(), true) --> true - auto flush 설정
} catch (Exception e) {
e.printStackTrace();
} finally {
if(socket != null) {
try {
socket.close(); // try-catch 사용
} catch (IOException e) {
e.printStackTrace();
}
}
}
} // end of main
} // end of class
SeverFile에 Toggle BreakPoint 25, 38, 39 설정
package ch02;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
public class SeverFile {
public static void main(String[] args) {
// 준비물
// 1. 서버 소켓이 필요하다.
// 2. 포트 번호가 필요하다. 개인한테(0번 부터 ~ 65535번 까지 존재한다.)
// 2. 1 잘 알려진 포트 번호 : 주로 시스템 레벨 0 ~ 1023까지 사용
// 2. 2 등록 가능하는 포트 : 1024 ~ 49151 까지 등록 가능하다.
// 2. 3 동적 / 사설 포트번호 - 그 외 임시 사용
// 지역 변수
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(5001);
System.out.println("서버를 시작합니다. 포트 번호 : 5001 ");
Socket socket = serverSocket.accept();
System.out.println(">>> 클라이언트가 연결 하였습니다. <<<");
// 데이터를 전달 받기 위해서는 뭐가 필요하다? --> 스트림이 하다.
InputStream input = socket.getInputStream();
// 문자기반 스트림
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
// 실제 데이터를 읽는 행위가 필요 하다.
String message = reader.readLine();
System.out.println("클리이언트 측 메세지 전달 받음 : " + message);
socket.close(); // try - catch - resource 안쓰면 직접 자원을 닫아 줘야 한다.
} catch (Exception e) {
e.printStackTrace();
} finally {
if (serverSocket != null) {
try {
serverSocket.close(); // 닫을 때도 예외가 발생 할 가능성이 있기에 try- catch 사용
} catch (IOException e) {
e.printStackTrace();
}
}
}
} // end of mainb
} // end of class
PrintWriter 사용 이유
- 편리한 메서드
print(), println(), **printf()**와 같은 메서드를 제공하여 다양한 형식의 데이터를 손쉽게 출력할 수 있습니다. - 자동 플러시(autoFlush)
PrintWriter를 생성할 때 autoFlush를 true로 설정하면, println() 등의 메서드를 호출할 때 자동으로 버퍼가 플러시되어 데이터를 즉시 전송합니다. 이는 네트워크 소켓과 같이 실시간 데이터 전송이 중요한 경우에 유용합니다. - 버퍼링
출력 데이터를 버퍼에 저장한 후 한 번에 출력하여 성능을 향상시킵니다.
필요시 flush() 메서드를 호출하여 강제로 데이터를 출력할 수도 있습니다.
주요 메서드
- print(): 다양한 데이터 타입을 출력합니다. (문자열, 정수, 부동 소수점 등)
- println(): 데이터를 출력하고 새로운 줄로 이동합니다.
- flush(): 버퍼를 강제로 플러시하여 출력 스트림에 데이터를 씁니다.
- close(): 출력 스트림을 닫습니다.
주의사항
- 예외 처리: PrintWriter는 메서드 호출 중 발생하는 입출력 예외를 던지지 않고 내부적으로 처리하므로, 스트림 상태를 주기적으로 확인하거나 명시적으로 checkError() 메서드를 호출하여 오류를 확인해야 합니다.
로컬호스트와 루프백(Loopback) 개념
로컬호스트(Localhost)
- 개념: 로컬호스트는 현재 사용 중인 컴퓨터 자체를 나타내는 용어입니다.
네트워크 프로그래밍에서 로컬호스트는 localhost 또는 IP 주소 127.0.0.1 로 표현됩니다. - 용도: 네트워크 애플리케이션을 개발하거나 테스트할 때, 외부 네트워크에 의존하지 않고 자신의 컴퓨터에서 서버와 클라이언트를 실행하여 통신을 시도할 수 있습니다.
루프백(Loopback)
- 개념: 루프백은 네트워크 장치가 자신에게 데이터를 보내는 가상의 네트워크 인터페이스입니다. 127.0.0.1 주소를 통해 루프백 인터페이스로 데이터를 보내면, 데이터는 외부 네트워크로 나가지 않고 즉시 자신에게 돌아옵니다.
- 용도: 네트워크 소프트웨어를 개발하거나 디버깅할 때, 외부 네트워크 환경 없이 로컬에서 모든 테스트를 수행할 수 있습니다.
+----------------------------+
| Your Computer |
| (localhost / 127.0.0.1) |
| |
| +-------------+ |
| | Application | |
| +-------------+ |
| | |
| v |
| +-------------+ |
| | System Call | |
| +-------------+ |
| | |
| v |
| +-------------+ |
| | Network | |
| | Stack | |
| +-------------+ |
| | |
| v |
| Loopback Interface |
| ^ |
| | |
| +-------------+ |
| | Network | |
| | Stack | |
| +-------------+ |
| | |
| v |
| +-------------+ |
| | Application | |
| +-------------+ |
| |
+----------------------------+
'Java' 카테고리의 다른 글
| 2024.05.22 Java 유용한 클래스 1:1 양방향 통신(채팅 기본 기능 구현) (0) | 2024.05.22 |
|---|---|
| 2024.05.22 Java 유용한 클래스 1:1 양방향 통신 (0) | 2024.05.22 |
| 2024.05.22 Java 유용한 클래스 1:1 단방향 통신 (서버측) (0) | 2024.05.22 |
| 2024.05.22 Java 유용한 클래스 Socket 이란 뭘까? (0) | 2024.05.22 |
| 2024.05.22 Spring Tools 4 for Eclipse 설치 및 설정 (0) | 2024.05.22 |