서버 작동 원리
기본적인 서버 프로그램은 어떤 객체가 필요할까요? 클라이언트의 요청을 계속해서 감시해야 합니다. 이는 고객 응대원처럼 사용자 요청을 적절한 서비스 부서로 전달하는 역할을 하며, ServerSocket이 이 작업을 담당합니다. 데이터를 전달하기 위한 Socket 연결도 필요하며, 나머지는 데이터를 읽고 쓰는 일반적인 작업입니다.
서버의 기본 작동 절차는 다음과 같습니다:
- ServerSocket을 생성하여 특정 포트에서 들어오는 요청을 감시합니다;
- 클라이언트가 서버의 지정된 포트로 요청을 보냅니다;
- 서버는 요청을 받은 후 데이터 전송을 위한 새로운 Socket 객체를 생성합니다;
- ServerSocket은 다른 클라이언트의 요청을 계속해서 감시합니다.
이것이 바로 서버의 기본 작동 방식입니다.
간단한 서버 구현
아래는 매우 간단한 서버 구현 예제입니다. 클라이언트 요청이 들어올 때마다 무작위 메시지를 반환하는 기능만 수행합니다.
import java.net.*;
import java.io.*;
/**
* SimpleChatServer.java
* 클라이언트 요청 시 무작위 메시지를 반환하는 간단한 서버
*/
public class SimpleChatServer {
// 무작위로 선택될 메시지 배열
String[] adviceList = {
"작은 입으로 음식을 드세요.",
"헐렁한 청바지를 선택하세요. 그건 당신을 뚱해 보이게 만들지 않아요. ",
"한 단어: 부적절해요.",
"오늘만큼은 솔직해지세요. 보스에게 당신이 *정말* 생각하는 말을 해보세요",
"그 헤어스타일은 다시 생각해볼 필요가 있어요."
};
// ServerSocket을 생성하여 지정된 포트에서 클라이언트 요청을 감시합니다.
// 요청이 들어오면 ServerSocket이 Socket 통신 연결을 생성하고 무작위 메시지를 반환합니다.
public void startServer() {
try {
// 5000번 포트에서 요청을 감시
ServerSocket serverListener = new ServerSocket(5000);
while (true) {
Socket clientConnection = serverListener.accept(); // 요청 수시 후 Socket 반환
PrintWriter outputWriter = new PrintWriter(clientConnection.getOutputStream());
String randomMessage = getRandomAdvice();
System.out.println("전송된 메시지: " + randomMessage);
outputWriter.println(randomMessage);
outputWriter.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
// 무작위 메시지 하나를 반환
private String getRandomAdvice() {
int randomIndex = (int) (Math.random() * adviceList.length);
return adviceList[randomIndex];
}
// 프로그램 실행 시작점
public static void main(String[] arguments) {
new SimpleChatServer().startServer();
}
}
간단한 클라이언트 구현
아래는 간단한 클라이언트 클래스입니다. 프로그램 실행 시 Socket 연결을 먼저 생성하고, 서버로부터 무작위 메시지를 받아 콘솔에 출력합니다.
import java.net.*;
import java.io.*;
/**
* SimpleChatClient.java
* 서버로부터 메시지를 받을 수 있는 간단한 클라이언트
*/
public class SimpleChatClient {
// Socket 연결을 설정하고 서버로부터 메시지를 수신합니다.
public void connectToServer() {
try {
// Socket 연결 설정 (127.0.0.1은 로컬 호스트 주소, 5000은 서버 포트)
Socket serverConnection = new Socket("127.0.0.1", 5000);
// 서버로부터 데이터 읽기
InputStream dataStream = serverConnection.getInputStream();
InputStreamReader streamReader = new InputStreamReader(dataStream);
BufferedReader messageReader = new BufferedReader(streamReader);
// 문자열 읽기
String receivedMessage = messageReader.readLine();
System.out.println("오늘의 조언: " + receivedMessage);
messageReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
// 프로그램 실행 시작점
public static void main(String[] args) {
new SimpleChatClient().connectToServer();
}
}
클라이언트와 서버의 상호작용
구현된 서버 프로그램이 어떻게 작동하는지 확인해 보겠습니다. 먼저 서버를 시작하여 5000번 포트에서 클라이언트 요청을 감시합니다.
그런 다음 클라이언트를 시작하여 메시지를 요청합니다. 클라이언트를 세 번 실행한 결과는 다음과 같습니다:
여기서 볼 수 있듯이, 클라이언트는 서버로부터 세 가지 다른 '조언'을 성공적으로 받았습니다.
참고로 위 예제는 동일한 머신에서 구현한 것입니다. 여러 대의 컴퓨터에서 테스트할 수도 있지만, 그 경우 서버 IP 주소와 포트 번호를 수정해야 합니다.
다음 내용 예고
다음 내용은 여러 작업을 동시에 처리하는 작업에 관한 것입니다. 현재 학습한 지식만으로는 이를 구현할 수 없습니다. 따라서 Java의 멀티스레딩 처리에 대해 먼저 학습할 필요가 있습니다. 다음 글부터는 Java 스레드 내용으로 전환됩니다.