자바 네트워크 프로그래밍 – TCP/IP와 소켓 프로그래밍
15장은 자바에서 네트워크 프로그래밍을 다루며, 특히 TCP/IP 프로토콜과 소켓 프로그래밍을 중심으로 설명하고 있습니다. TCP/IP 기반의 클라이언트-서버 통신 방식과 소켓을 이용한 데이터 송수신 방법을 배울 수 있습니다.
1. TCP/IP 개요
TCP/IP는 인터넷을 기반으로 하는 네트워크 통신 프로토콜입니다. 이 중 TCP(Transmission Control Protocol)는 신뢰성 있는 데이터 전송을 담당하고, IP(Internet Protocol)는 패킷을 목적지로 전달하는 역할을 합니다.
IP 주소와 포트
- IP 주소: 네트워크 상에서 각 장치를 식별하는 고유한 주소. IPv4, IPv6 주소 체계를 사용합니다.
- 포트: 특정 응용 프로그램이 데이터를 송수신할 때 사용하는 가상의 통신 단위입니다. 각 프로그램은 고유한 포트 번호를 사용하여 네트워크 상에서 통신합니다.
2. 소켓 프로그래밍
소켓(Socket)은 네트워크 통신에서 두 프로그램 간의 연결을 담당하는 양방향 통신의 끝단입니다. 자바에서 java.net
패키지를 사용해 소켓을 구현할 수 있습니다.
소켓과 서버소켓
- 소켓(Socket): 클라이언트 측에서 서버에 접속하는 통신의 끝점입니다.
- 서버소켓(ServerSocket): 서버 측에서 클라이언트의 접속을 기다리는 소켓입니다.
소켓 통신 과정
- 서버는
ServerSocket
을 통해 클라이언트의 요청을 대기하고, 클라이언트는Socket
을 통해 서버에 접속 요청을 보냅니다. - 서버는 클라이언트의 연결 요청을 수락하여 소켓을 생성하고, 클라이언트와 데이터를 주고받습니다.
- 데이터를 주고받은 후 소켓을 닫아 통신을 종료합니다.
3. 소켓을 이용한 서버-클라이언트 예제
서버 코드 예제
import java.io.*;
import java.net.*;
public class ServerEx {
public static void main(String[] args) {
try (ServerSocket listener = new ServerSocket(9999);
Socket socket = listener.accept();
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()))) {
System.out.println("클라이언트와 연결되었습니다.");
while (true) {
String inputMessage = in.readLine(); // 클라이언트로부터 메시지 수신
if (inputMessage.equalsIgnoreCase("bye")) {
System.out.println("클라이언트가 연결을 종료했습니다.");
break;
}
System.out.println("클라이언트: " + inputMessage);
out.write("서버: " + inputMessage + "\n");
out.flush();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
클라이언트 코드 예제
import java.io.*;
import java.net.*;
import java.util.Scanner;
public class ClientEx {
public static void main(String[] args) {
try (Socket socket = new Socket("localhost", 9999);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
Scanner scanner = new Scanner(System.in)) {
while (true) {
System.out.print("보내기>> ");
String outputMessage = scanner.nextLine();
if (outputMessage.equalsIgnoreCase("bye")) {
out.write(outputMessage + "\n");
out.flush();
break;
}
out.write(outputMessage + "\n");
out.flush();
System.out.println(in.readLine());
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
이 예제에서는 클라이언트가 메시지를 서버로 전송하고, 서버는 이를 수신한 후 응답을 보내는 간단한 채팅 프로그램을 구현합니다.
4. 수식 계산 서버-클라이언트 실습
다음은 서버가 클라이언트로부터 수식을 받아 계산한 결과를 돌려주는 프로그램입니다.
서버 코드 (CalcServerEx.java)
import java.io.*;
import java.net.*;
import java.util.StringTokenizer;
public class CalcServerEx {
public static String calc(String exp) {
StringTokenizer st = new StringTokenizer(exp, " ");
if (st.countTokens() != 3) return "error";
int op1 = Integer.parseInt(st.nextToken());
String opcode = st.nextToken();
int op2 = Integer.parseInt(st.nextToken());
switch (opcode) {
case "+": return Integer.toString(op1 + op2);
case "-": return Integer.toString(op1 - op2);
case "*": return Integer.toString(op1 * op2);
default: return "error";
}
}
public static void main(String[] args) {
try (ServerSocket listener = new ServerSocket(9999);
Socket socket = listener.accept();
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()))) {
System.out.println("연결되었습니다.");
while (true) {
String inputMessage = in.readLine();
if (inputMessage.equalsIgnoreCase("bye")) {
System.out.println("클라이언트가 연결을 종료했습니다.");
break;
}
String result = calc(inputMessage);
out.write(result + "\n");
out.flush();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
클라이언트 코드 (CalcClientEx.java)
import java.io.*;
import java.net.*;
import java.util.Scanner;
public class CalcClientEx {
public static void main(String[] args) {
try (Socket socket = new Socket("localhost", 9999);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
Scanner scanner = new Scanner(System.in)) {
while (true) {
System.out.print("계산식(빈칸으로 띄어 입력, 예: 24 + 42)>> ");
String outputMessage = scanner.nextLine();
if (outputMessage.equalsIgnoreCase("bye")) {
out.write(outputMessage + "\n");
out.flush();
break;
}
out.write(outputMessage + "\n");
out.flush();
System.out.println("계산 결과: " + in.readLine());
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
마무리
네트워크 프로그래밍은 클라이언트-서버 모델을 기반으로 동작하며, 자바의 Socket
과 ServerSocket
클래스를 사용하여 간단하게 구현할 수 있습니다. 이를 통해 프로그램 간의 데이터 송수신 및 실시간 통신이 가능하며, TCP/IP 프로토콜을 이해하는 것이 중요합니다.
'Java' 카테고리의 다른 글
Java 제네릭 와일드카드에 대하여 (0) | 2024.11.18 |
---|---|
명품자바 프로그래밍의 기초: 14장 (0) | 2024.09.18 |
명품자바 프로그래밍의 기초: 13장 (0) | 2024.09.17 |
명품자바 프로그래밍의 기초: 12장 (0) | 2024.09.15 |
명품자바 프로그래밍의 기초: 11장 (0) | 2024.09.13 |