
네트워크 통신에서 서버와 통신하려면 IP 주소가 필요하다. 도메인(호스트 이름)만으로는 통신할 수 없으며, 도메인을 실제 IP 주소로 변환해야 한다.
자바에서는 InetAddress 클래스를 사용하여 도메인 이름을 IP 주소로 변환할 수 있다.
import java.net.*;
public class HostToIP {
public static void main(String[] args) {
try {
InetAddress address = InetAddress.getByName("www.google.com");
System.out.println("IP Address: " + address.getHostAddress());
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
}
소켓 통신에서 데이터를 주고받을 때 InputStream과 OutputStream을 사용한다.
하지만, 기본 스트림을 그대로 사용하면 byte 단위로 데이터를 변환해야 하는 불편함이 있다. 이를 해결하기 위해 보조 스트림을 사용한다.
DataInputStream과 DataOutputStream을 사용하면 자바 기본 타입(int, float, String 등) 을 편리하게 송수신할 수 있다.
import java.io.*;
import java.net.*;
public class Client {
public static void main(String[] args) {
try (Socket socket = new Socket("localhost", 12345);
DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
DataInputStream dis = new DataInputStream(socket.getInputStream())) {
dos.writeUTF("Hello Server"); // 문자열 전송
System.out.println("Server response: " + dis.readUTF()); // 응답 수신
} catch (IOException e) {
e.printStackTrace();
}
}
}
서버는 특정 포트를 열어두어야 클라이언트가 접속할 수 있다.
ServerSocket을 생성하고 특정 포트(예: 12345)에서 대기accept()를 호출하여 클라이언트 요청을 대기Socket 객체를 생성하여 통신import java.io.*;
import java.net.*;
public class Server {
public static void main(String[] args) {
try (ServerSocket serverSocket = new ServerSocket(12345)) {
System.out.println("서버 대기 중...");
while (true) {
Socket socket = serverSocket.accept(); // 클라이언트 연결 대기 (블로킹)
System.out.println("클라이언트 연결 완료!");
new Thread(new ClientHandler(socket)).start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
class ClientHandler implements Runnable {
private Socket socket;
public ClientHandler(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
try (DataInputStream dis = new DataInputStream(socket.getInputStream());
DataOutputStream dos = new DataOutputStream(socket.getOutputStream())) {
String message = dis.readUTF(); // 클라이언트 메시지 수신
System.out.println("Received: " + message);
dos.writeUTF("Hello Client!"); // 응답 전송
} catch (IOException e) {
e.printStackTrace();
}
}
}
accept() 메서드는 클라이언트 연결 요청이 없으면 무한 대기 상태(블로킹)가 된다.readUTF() 같은 입력 메서드도 데이터를 받을 때까지 대기 상태가 된다.각 클라이언트가 연결될 때마다 새로운 Thread를 생성하여 별도로 처리하면, 여러 클라이언트를 동시에 처리할 수 있다.
ServerSocket을 관리하고 새로운 연결이 올 때마다 Session 스레드를 생성✅ 서버 소켓과 클라이언트 소켓
ServerSocket은 연결만 담당하는 특별한 소켓Socket 객체를 통해 이루어짐✅ TCP 연결 과정
connect() 요청하면 TCP 3-Way Handshake 후 Backlog Queue에 저장accept() 호출 시 Socket 객체 생성 후 클라이언트와 통신 가능✅ 스트림을 이용한 데이터 송수신
DataInputStream / DataOutputStream을 활용하면 편리한 데이터 송수신 가능✅ 멀티스레드 처리 필요
accept()와 readUTF() 같은 블로킹 메서드는 별도 스레드에서 실행해야 함이제 자바 소켓 프로그래밍에 대한 기본 개념을 정리했으니, 실전 프로젝트에서 활용해 보자! 🚀