Java

Socket

ryeonng 2024. 6. 12. 16:43

소켓(Socket)

소켓은 컴퓨터 네트워킹에서 매우 중요한 역할을 하며, 특히 자바 I/O 에서 자주 사용된다.
소켓은 네트워크 상에서 통신을 가능케 하는 끝점을 의미한다. 두 컴퓨터 간의 데이터를 주고받기 위해 사용되는 인터페이스로, 소켓을 통해 네트워크 연결을 설정하고 데이터를 송수신할 수 있다.
쉽게 말해, 소켓은 네트워크를 통해 다른 컴퓨터와 대화하는 전화기 역할을 한다. (소켓은 사실, 파일 개념과 같다.)

소켓은 물리적인 장치가 아니라 추상적인 개념의 약속이다. 네트워크 통신을 위해 소프트웨어적으로 정의 된 인터페이스로, 컴퓨터 간의 데이터 교환을 가능하게 하는 규칙과 방법을 의미한다. 이를 통해 네트워크 애플리케이션이 서로 통신할 수 있다.

 

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

네트워크 인터페이스 카드 (NIC) / 랜카드 (LAN Card)
· 역할
: 컴퓨터를 네트워크에 연결하는 장치
· 유형 
 : - 유선 NIC (이더넷 카드) : 이더넷 케이블을 통해 네트워크에 연결한다.
   - 무선 NIC (와이파이 카드) : 무선 신호를 통해 네트워크에 연결한다.

 


소켓의 종류

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

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

 


 

소켓의 동작 방식

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

  1. 서버 측 :· 소켓을 생성하고 포트 번호와 결합(Binding) 한다. · 클라이언트의 연결 요청을 대기(Listening)한다. · 클라이언트의 연결 요청을 수락(Accept)하고 통신할 준비를 한다.
  2. 클라이언트 측 : · 소켓을 생성하고 서버의 주소와 포트 번호로 연결(Connection)을 요청한다. · 서버와 연결이 성공되면 데이터를 송수신할 수 있다.

 


 

자바에서의 소켓 프로그래밍

자바에서는 java.net 패키지를 사용하여 소켓 프로그래밍을 할 수 있다.

 

서버 측 기본 코드
package 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)) { // 포트번호 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();
		}
	}

}

 

클라이언트 측 기본 코드
package 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 <- 자신의 IP주소 (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();
		}
	}
	
}

 


 

소켓 프로그래밍의 응용

소켓 프로그래밍은 다양한 응용 분야에 사용된다.

  • 웹 서버와 클라이언트 간 통신
  • 파일 전송
  • 채팅 어플리케이션
  • 멀티플레이어 게임