▶ 네트워크 (Network)
- 여러 대의 컴퓨터를 통신 회선으로 연결한 것(홈 네트워크, 지역 네트워크, 인터넷 등)
- 여러 통신기기를 서로 연결하여 데이터를 손쉽게 주고받거나 자원 등을 공유하기 위해 사용
1) 서버 (Server)와 클라이언트 (Client)
- 네트워크로 연결된 컴퓨터 간의 관계를 역할(role)로 구분한 개념
- 서버(Server)는서비스를 제공하는 컴퓨터 또는 프로그램으로,
클라이언트의 연결을 수락하고 요청 내용을 처리 후 응답을 보내는 역할 - 클라이언트(Client)는 서버에 서비스를 요청하여 사용하는 컴퓨터 또는 프로그램으로,
네트워크 데이터를 필요로 하는 모든 어플리케이션이 해당됨
2) IP 주소
- 네트워크 상에서 컴퓨터를 식별하는 번호로,
네트워크 어댑터(랜카드)마다 할당되어 있음
3) 포트 (Port)
- 같은 컴퓨터 내에서 프로그램을 식별하는 번호로,
클라이언트는 서버연결 요청 시 IP 주소와 포트(Port) 번호를 알아야 함
▶ 소켓 (Socket) 프로그래밍
- 소켓을 이용한 통신 프로그래밍
1) 소켓 (Socket)
- 프로세스 간의 통신에 사용되는 양쪽 끝단
- 서버와 클라이언트가 통신하기 위한 매개체
2) 프로토콜 (Protocol)
- 컴퓨터 간의 정보를 주고 받을 때의 통신방법에 대한 규약으로,
접속, 전달방식, 데이터의 형식, 검증 방법 등을 맞추기 위한 약속
3) TCP (Transmission Control Protocol)
- 데이터 전달의 신뢰성을 최대한 보장하기 위한 방식으로 연결 지향형 통신
- 순차적으로 데이터를 전송하고 확인 및 오류 시 재전송을 함
▶ TCP 소켓 프로그래밍
- 클라이언트와 서버 간의 1:1 소켓 통신
- 서버가 먼저 실행되어 클라이언트의 요청을 기다려야 하고,
서버용 프로그램과 클라이언트용 프로그램을 따로 구현해야 함 - 자바에서는 TCP 소켓 프로그래밍을 위해 java.net 패키지에서 ServerSocket과 Socket 클래스 제공
1) 서버용 TCP 소켓 프로그래밍 순서
- ServerSocket : 서버용 소켓 :
- 포트(Port)와 연결되어 외부 요청을 기다리는 역할
→ 클라이언트 요청이 올 경우 이를 수락(accept)하고, 클라이언트가 사용할 수 있는 소켓을 생성
→ 서버 소켓과 클라이언트 소켓이 연결되어 데이터 통신이 가능해짐
public void serverStart() {
// *사용할 변수 미리 선언*
// 1) 소켓
ServerSocket seso = null; // 서버 소켓 저장 변수
Socket clso = null; // 클라이언트 소켓 저장 변수
// 2) 입력스트림
InputStream is = null; // 클라이언트 -> 서버 입력용 스트림 변수 (서버 기준)
BufferedReader br = null; // 입력용 보조 스트림 변수
// 3) 출력스트림
OutputStream os = null; // 서버 -> 클라이언트 출력용 스트림 변수 (서버 기준)
PrintWriter pw = null; // 출력용 보조 스트림 변수
// 1.서버의 포트번호 정함
int port = 8500; // port 번호는 0~65535 사이 지정 가능
// 단, 1023번 이하는 이미 사용 중인 경우가 많아서 제외
try {
// 서버 컴퓨터(내 컴퓨터)의 IP 관련 정보를 얻어옴
InetAddress inet = InetAddress.getLocalHost();
// 2.서버용 소켓 객체 생성
seso = new ServerSocket(port); // 서버용 소켓을 생성하여 포트 결합
// 3.클라이언트쪽에서 접속요청이 오길 기다림
// - 서버용 소켓은 생성되면 클라이언트 요청이 오기 전까지
// 다음 코드를 수행하지 않고 대기하고 있음
System.out.println("[Server]");
System.out.println("클라이언트의 요청을 기다리고 있습니다...");
// 4.접속요청이 오면 요청 수락 후 해당 클라이언트에 대한 소켓 객체 생성
// -> 요청을 수락하면 자동으로 Socket 객체가 얻어와짐
clso = seso.accept();
// 접속한 클라이언트의 IP를 얻어와 출력
String clientIP = clso.getInetAddress().getHostAddress();
System.out.println(clientIP + "가 연결을 요청함");
// 5.연결된 클라이언트와 입출력 스트림 생성
is = clso.getInputStream(); // 클라이언트 -> 서버 입력
os = clso.getOutputStream(); // 서버 -> 클라이언트 출력
// 6.보조 스트림을 통해 성능 개선
br = new BufferedReader( new InputStreamReader(is) );
// InputStreamReader : 문자 기반 스트림과 바이트 기반 스트림 연결에 사용되는 스트림
pw = new PrintWriter(os);
// 7.스트림을 통해 읽고 쓰기
// 7-1) 서버 -> 클라이언트에게 출력(메세지 전송)
pw.println("[서버 접속 성공]");
pw.flush(); // 스트림(버퍼)에 기록된 내용을 밀어내는 코드
// -> 미작성 시 클라이언트쪽으로 출력 X
// 7-2) 클라이언트 -> 서버에게 입력(메세지 전송 받기)
String clientMessage = br.readLine(); // 클라이언트 메시지 한 줄을 읽어옴
System.out.println(clientIP+"로부터 받은 메세지 : "+clientMessage);
} catch (IOException e) {
e.printStackTrace(); // 예외 추적
} finally { // try 구문에서 예외 발생 여부 관계 없이 무조건 수행
// 8.통신 종료
// 사용한 스트림, 소켓 자원을 모두 반환(close)
// -> 메모리 누수 관리
// 보통 소켓, 스트림 생성 역순으로 close() 구문을 작성
try {
// 보조 스트림 close 시 연결된 기반 스트림(is,os)도 같이 close됨
if(pw != null) pw.close(); // + os.close()
if(br != null) br.close(); // + is.close()
if(clso != null) clso.close();
if(seso != null) seso.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
2) 클라이언트용 TCP 소켓 프로그래밍 순서
public class TCPClient {
public void clientStart() {
/* 필요한 변수 선언 */
Socket clso = null; // 서버와 연결할 클라이언트용 소켓을 저장할 변수
BufferedReader br = null; // 서버 -> 클라이언트로 읽어오는 보조 스트림
PrintWriter pw = null; // 클라이언트 -> 서버로 출력하는 보조 스트림
// 1. 서버의 IP 주소와 서버가 정한 포트 번호를 매개변수로 하여 클라이언트용 소켓 객체 생성
String serverIP = "127.0.0.1"; // loop back ip(내 컴퓨터를 가리키는 ip주소)
int port = 8500; // 서버 소켓이 기다리고 있는 포트 번호 작성
try {
// 2. 서버와의 입출력 스트림 오픈 -> 먼저 소켓이 필요함
System.out.println("[Client]");
clso = new Socket(serverIP,port); // 클라이언트용 소켓 객체(서버 IP주소,포트) 생성
// 3. 보조 스트림을 통해 성능 개선
// 2 & 3번 동시 진행
br = new BufferedReader( new InputStreamReader( clso.getInputStream()));
pw = new PrintWriter( clientSocket.getOutputStream());
// 4. 스트림을 통해 읽고 쓰기
// 4-1) 서버 접속 성공 시
// 서버가 출력한 "[서버 접속 성공]" 메시지 읽어오기
String message = br.readLine();
System.out.println("서버로부터 받은 메시지 : " + message);
// 4-2) 클라이언트 -> 서버로 메시지 전송
Scanner sc = new Scanner(System.in);
System.out.print("입력 : ");
String input = sc.nextLine();
pw.println(input);
pw.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
// 5. 통신 종료
try {
if(br != null) br.close();
if(pw != null) pw.close();
if(clso != null) clso.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
'Java > 기본 개념' 카테고리의 다른 글
변수(Variable) (0) | 2024.12.16 |
---|---|
프로그래밍 기초 (0) | 2024.12.16 |
컬렉션(Collection) (2) | 2024.11.17 |
스레드(Thread) (0) | 2024.11.17 |
입출력 (IO_Input / Output) (3) | 2024.11.17 |