네트워크에서 두 애플리케이션 간 데이터 교환을 가능하게 하는 양방향 통신 방식.
모든 소켓은 포트 번호를 가지고 있어, 해당 포트를 통해 프로세스를 식별.
통신 시 IP 주소와 포트 번호가 모두 필요.
데이터 송수신 시 반드시 버퍼(Buffer)를 사용.
- bw(Buffer Write): 데이터를 보내기 위한 전송 버퍼.
- br(Buffer Read): 데이터를 받기 위한 수신 버퍼.
전송 방식
1. 단방향 통신
- 데이터를 한쪽 방향만 전송.
- 사용 예: 라디오 방송처럼 송신자가 일방적 데이터 전송.
2. 반이중 통신 (Half-Duplex)
- 한 번에 하나의 방향만 데이터 전송 가능.
- 작동 원리:
- 송신(
bw
) 중에는 수신(br
) 대기 상태. - 수신 시 이벤트가 발생해 데이터를 처리.
- 특징:
- 통신 채널이 한 개.
- 요청이 있을 때만 데이터 교환(수동적).
- 사용 예: 무전기, 일반적인 요청-응답 웹 서버.
3. 전이중 통신 (Full-Duplex)
- 동시에 양방향 데이터 전송 가능.
- 작동 원리:
- 두 개의 통신 채널을 사용하거나, 스레드를 활용해 병렬 처리.
- 송신(
bw
)과 수신(br
)이 동시에 동작.
- 특징:
- 통신이 능동적.
- 실시간 데이터 교환에 적합.
- 사용 예: 웹소켓, 화상회의.
통신 흐름
하드웨어(HS) → 운영 체제(OS) → 애플리케이션(App)
1. 하드웨어(Hardware)
- 네트워크 카드(NIC)가 물리적 데이터를 송수신.
- 데이터를 OS로 전달.
2. 운영 체제(OS)
- 커널이 네트워크 계층의 데이터를 처리.
- 애플리케이션과 통신하기 위해 파일 인터페이스를 제공.
3. 애플리케이션(App)
- 소켓(Socket) 생성:
- OS의 파일 인터페이스를 사용해 소켓을 생성.
- 소켓은 IP 주소와 포트를 사용해 통신.
- 데이터를 전송(
bw
)하거나 수신(br
)하며, 통신을 완성.
구현 코드
- MyServer
public class MyServer {
public static void main(String[] args) throws IOException {
try {
ServerSocket serverSocket = new ServerSocket(10000); // 1. 서버포켓 생성
Socket socket = serverSocket.accept(); // 2. 리스닝
System.out.println("oh! connect?");
BufferedReader br = new BufferedReader(
// 소켓으로 부터 input 읽음
new InputStreamReader(socket.getInputStream())
);
String line = br.readLine(); // 버퍼에 있는 메세지를 \n까지 읽는다
System.out.println("read : " + line); // 읽고 끝. 쓰려면 밑에 bw 구현
} catch (IOException e) {
e.printStackTrace();
}
}
}
- MyClient
public class MyClient {
public static void main(String[] args) throws IOException {
Socket socket = new Socket("localhost", 10000); // 로컬호스트와 포트 필요
PrintWriter pw = new PrintWriter(socket.getOutputStream(), true);
pw.println("Hello World");
// BufferedWriter bw = new BufferedWriter(
// new OutputStreamWriter(socket.getOutputStream())
// );
//
// // 프로토콜 통신 약속: \n 붙임.없으면 터진다
// // bw여러개면 마지막에만 \n 붙이기
// bw.write("Hello World\n"); // 글작성
// bw.flush(); // 전송
}
}
1.
PrintWriter
- 문자열 출력에 특화되어 있음.
- 다양한 데이터 타입(
int
,float
,String
등)을 텍스트 형태로 출력 가능. - 자동으로 줄바꿈이나 포맷팅 지원 (e.g.,
println
,printf
). - autoFlush 옵션 지원:
true
로 설정 시println
또는printf
실행 후 자동으로 플러시.
- 다목적, 직관적인 출력 방식 제공.
- 줄바꿈이 포함된 출력을 쉽게 처리.
2.
BufferedWriter
- 출력 데이터를 임시 저장 후 한 번에 전송하여 입출력 성능을 향상.
- 줄바꿈과 같은 포맷팅은 수동으로 처리해야 함.
- 데이터가 버퍼에 남아있을 수 있으므로 항상
flush()
호출 필요.
- 대량의 데이터를 처리할 때 효율적.
- 데이터 출력의 세밀한 제어 가능.
- MyWriter
기존
BufferedWriter
의 기능에 자동 플러시(autoFlush) 및println
메서드를 추가하여 편의성을 높인 커스텀 클래스
public class MyWriter extends BufferedWriter {
private boolean autoFlush = false;
public MyWriter(OutputStream stream) {
super(new OutputStreamWriter(stream));
}
public MyWriter(OutputStream stream, boolean autoFlush) {
super(new OutputStreamWriter(stream));
this.autoFlush = autoFlush;
}
public void println(String msg) {
try {
this.write(msg);
this.write("\n");
if (autoFlush) {
this.flush();
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
동작 과정
- 생성자
OutputStream
을 받아 **OutputStreamWriter
*로 변환 후, BufferedWriter
로 초기화.기본 생성자:
autoFlush = false
.추가 생성자:
autoFlush
값을 설정.println
메서드BufferedWriter
는 기본적으로 줄바꿈 메서드가 없지만,println
을 추가하여 이를 간단히 처리 가능.PrintWriter
처럼autoFlush
기능을 제공하여 데이터 전송을 자동화 가능.- 표준
BufferedWriter
의 동작을 확장하여 특정 환경(예: 통신 프로토콜 요구 사항)에 맞게 동작을 조정.
주어진 문자열을 출력(
write
)한 뒤 줄바꿈(\n
) 추가.autoFlush
가 활성화된 경우, 출력 후 즉시 flush()
호출.코드 장점
편리한 줄바꿈 지원
자동 플러시 지원
커스터마이징 가능
Share article