Java/네트워크 통신

[Java] 92. Socket이란?

Song hyun 2024. 5. 22. 12:46
728x90
반응형

[Java] 92. Socket이란?

1. 소켓의 개념

2. 소켓의 종류

3. 소켓의 동작 방식

4. Java 에서의 소켓 프로그래밍

5. 시나리오 코드 : 소켓 통신을 해보자

 


 

1. 소켓의 개념

(1) 소켓(Socket): 소켓은 네트워크 상에서 통신을 가능하게 하는 끝점을 의미한다. 두 컴퓨터 간의 데이터를 주고 받기 위해 사용되는 인터페이스로, 우리는 소켓을 통해 네트워크 연결을 설정하고, 데이터를 송수신할 수 있다.

=> 쉽게 말해, 소켓은 네트워크를 통해 다른 컴퓨터와 대화하는 전화기인 셈이다!

-> 소켓은 물리적인 장치가 아닌 추상적인 개념의 약속이다.
-> 소켓은 네트워크 통신을 위해 sw적으로 정의된 인터페이스이며, 컴퓨터 간의 데이터 교환을 가능하게 하는 규칙과 방법을 의미한다.

 

*일반 사용자 컴퓨터에서 네트워크 통신에 사용되는 주요 물리적 장치는 네트워크 인터페이스 카드(=NIC), 모뎀, 라우터, 스위치, 액세스 포인트, 그리고 이더넷 케이블이다. 이들은 함께 작동하여 인터넷 연결을 설정하고, 데이터 통신을 가능하게 한다.

 


2. 소켓의 종류

-소켓에는 크게 두 가지 주요 유형이 있다.

 

(1) 스트림 소켓(Stream Socket): TCP(Transmission Control Protocol) 기반의 소켓으로, 연결 지향적이다. 데이터를 안정적/순차적으로 에러 없이 전달한다. (ex: 웹 브라우저와 웹 서버간의 통신)
(2) 데이터그램 소켓(Datagram Socket): UDP(User Datagram Protocol) 기반의 소켓으로, 비연결 지향적이다. 데이터를 빠르게 전송하나, 데이터의 순서나 신뢰성이 보장되지 않는다. (ex: 실시간 게임, 스트리밍 서비스)


 

3. 소켓의 동작 방식

-소켓 통신은 다음과 같은 과정으로 이루어진다.

 

(1) 서버 측:

-소켓을 생성하고, 포트 번호와 결합(Binding)한다.

-클라이언트의 연결 요청을 대기(Listening)한다.

-클라이언트의 연결 요청을 수락(Accept)하고, 통신할 준비를 한다.

 

(2) 클라이언트 측:

-소켓을 생성하고, 서버의 주소와 포트 번호로 연결(Connection)을 요청한다.

-서버와 연결이 성공하면 데이터를 송수신 할 수 있다.


 

4. Java 에서의 소켓 프로그래밍

*Java에서는 Java.net 패키지를 사용해 소켓 프로그래밍을 할 수 있다.

 

(1) 소켓과 서버 소켓

*클라이언트는 소켓만 있으면 되지만, 서버는 소켓/서버소켓(ServerSocket)을 둘 다 지니고 있어야 한다.

서버소켓은 클라이언트의 연결 요청을 받아들이고, 그 소켓과 연결되는 새로운 소켓을 생성하는 역할을 한다.(=등대?)

**ServerSocket.accept()는 클라이언트의 소켓과 연결되는 새로운 소켓을 만드는 역할을 한다!

 

(2) 소켓 프로그래밍의 응용: 소켓 프로그래밍은 다양한 분야에서 사용된다.

-웹 서버와 클라이언트 간의 통신

-파일 전송

-채팅 애플리케이션

-멀티플레이어 게임

 


5. 시나리오 코드 : 소켓 통신을 해보자

 

아래의 예제와 같이 코드를 작성해, 소켓 통신을 해보자.

localhost를 통해 자신의 컴퓨터 내에서도 소켓 프로그래밍-통신이 가능하다.(=Loopback 개념)

 

 

(1) 시나리오 코드: Server

package server_class_v1.ch01;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {

	public static void main(String[] args) {

		// 서버 측 소켓 통신을 만들기 위해서 준비물
		// 1. ServerSocket (클라이언트 측 소켓과 연결만 시켜준다.)
		// 2. 클라이언트와 연결 되는 소켓을 들고 있어야 한다.

		// 로컬 컴퓨터에는 정해진/사용할 수 있는 포트 번호 개수가
		// 할당되어 있다. 1~1024 포트 번호는 잘 알려진 포트 번호 시스템이
		// 선점하고 있는 번호들이다.

		try (ServerSocket serverSocket = new ServerSocket(5000)) {
			System.out.println("서버 포트 번호 : 5000으로 생성");
			// 내부 메서드 안에서 while 문을 돌면서 클라이언트 측에
			// 연결을 기다리고 있다.

			Socket socket = serverSocket.accept();
			// 여기 아래는 클라이언트 측과 양 끝단의 소켓이
			// 서로 연결되어야 실행 흐름이 내려온다.

			System.out.println("Client connected...");
			
			// 대상 - 소켓 --> 입력 스트림을 가져 온다.
			InputStream input = socket.getInputStream();
			BufferedReader reader = new BufferedReader(new InputStreamReader(input)); 
			String message = reader.readLine(); // 한줄 단위로 읽어라.(문자 기반)
			System.out.println("Received : "+message);
			
			// 기본 소켓은 클라이언트가 연결되어야 생성된다.
			socket.close();
			
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

}

 

(2) 시나리오 코드: Client

package client_class_v1.ch01;

import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;

public class Client {
	
	public static void main(String[] args) {
		// 클라이언트 측 -- 소켓 통신을 하기 위해 준비물
		// 1. 서버 측 컴퓨터의 주소:포트번호 <--가 필요하다.
		// 2. 서버측과 연결 될 기본 소켓이 필요하다.
		
		// 생성자 매개변수에 서버 측 (IP 주소, 포트 번호)
		// 127.0.0.1 = 자기 자신의 주소 = localhost
		try (Socket socket = new Socket("localhost",5000)){
			// new Socket("localhost",5000) --> 객체 생성시 서버측과 연결되어서
			// 스트림을 활용 할 수 있다.
			// 대상은 소켓이다!!!
			
			OutputStream output = socket.getOutputStream(); // 소켓에서 기반 스트림
			PrintWriter writer = new PrintWriter(output, true); // 기능 확장 - 보조 스트림
			writer.println("우산커피 스카치크림 맛있음");
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}

}
728x90
반응형