소켓이란
프로그램이 네트워크에서 데이터를 주고받을 수 있도록 네트워크 환경에 연결할 수 있게 만들어진 연결부로,
일반적으로 TCP/IP 프로토콜을 이용한다.
OSI 7계층 중 응용 계층에 속하는 프로세스들은 데이터 송수신을 위해 반드시 소켓을 거쳐
전송 계층으로 데이터를 전달해야한다.
즉, 소켓은 엔드포인트이다.(엔드포인트: 통신의 시작점과 끝점을 의미)
소켓은 Protocol, IP, Port 세 가지 요소로 구성된다.
- Protocol : 데이터 전송을 위한 규칙을 정의
- IP : 네트워크 상에서 각 기기를 구분하기 위한 주소
- Port : 프로세스 간의 통신을 구분하기 위한 번호
이 세 가지 요소를 통해 소켓은 네트워크 상에서 동작하는 두 개의 프로그램 간의 통신을 가능하게 한다.
예를 들어, 소켓에는 Client Socket과 Server Socket로 구분되는데
클라이언트 프로그램은 서버 프로그램에 연결하기 위해 소켓을 생성합니다. 클라이언트 소켓은 특정 IP 주소와 포트 번호를 사용하여 서버 소켓에 연결합니다. 서버 소켓은 클라이언트 소켓의 연결 요청을 수락하여 통신을 시작한다.
소켓 실행 흐름
서버
- socket() - 서버 소켓 생성
- bind() - 서버가 사용할 IP 주소와 포트 번호를 생성한 소켓에 결합
- listen() - 클라이언트로부터 연결 요청이 수신되는지 주시
- accept() - 요청이 수신되면 요청을 받아들여 데이터 통신을 위한 소켓을 생성
- send() · recv() - 데이터 송수신
- close() - 소켓 닫기
클라이언트
- socket() - 클라이언트 소켓 생성
- connect() - 서버에 설정된 IP와 포트 번호로 연결 시도
- send() · recv() - 데이터 송수신
- close() - 소켓 닫기
소켓 종류
스트림소켓
연결형 소켓의 일종으로, 데이터가 스트림 형태로 전송됩니다.
스트림 소켓은 TCP(Transmission Control Protocol) 프로토콜을 사용하며,
다음과 같은 특징을 가지고 있습니다.
- 연결을 맺은 후 데이터를 전송합니다.
- 데이터의 순서를 보장합니다.
- 데이터의 중복을 방지합니다.
- 오류를 수정합니다.
- 흐름 제어를 수행합니다.
스트림 소켓은 대량의 데이터를 안정적으로 전송해야 하는 경우에 적합합니다.
예를 들어, 파일 전송, 실시간 스트리밍, 게임 등에서 사용됩니다.
데이터그램 소켓
비연결형 소켓의 일종으로, 데이터가 패킷 형태로 전송됩니다.
데이터그램 소켓은 UDP(User Datagram Protocol) 프로토콜을 사용하며, 다음과 같은 특징을 가지고 있습니다.
- 연결을 맺지 않고 데이터를 전송합니다.
- 데이터의 순서를 보장하지 않습니다.
- 데이터의 중복이 발생할 수 있습니다.
- 오류를 수정하지 않습니다.
- 흐름 제어를 수행하지 않습니다.
데이터그램 소켓은 소량의 데이터를 빠르게 전송해야 하는 경우에 적합합니다.
예를 들어, DNS(Domain Name System), VoIP(Voice over Internet Protocol), 게임 등에서 사용됩니다.
자바 예제 코드
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
public static void main(String[] args) throws IOException {
// 서버 소켓 생성
ServerSocket serverSocket = new ServerSocket(8080);
// 클라이언트 연결 대기
Socket socket = serverSocket.accept();
// 입력 스트림, 출력 스트림 얻기
InputStream inputStream = socket.getInputStream();
OutputStream outputStream = socket.getOutputStream();
// 클라이언트로부터 데이터 수신
byte[] buffer = new byte[1024];
int length = inputStream.read(buffer);
// 수신한 데이터 출력
System.out.println("클라이언트로부터 수신한 데이터: " + new String(buffer, 0, length));
// 클라이언트로 데이터 전송
String message = "안녕하세요, 클라이언트님!";
outputStream.write(message.getBytes());
// 소켓 닫기
socket.close();
serverSocket.close();
}
}
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
public class Client {
public static void main(String[] args) throws IOException {
// 서버 주소 및 포트 지정
String host = "localhost";
int port = 8080;
// 클라이언트 소켓 생성
Socket socket = new Socket(host, port);
// 입력 스트림, 출력 스트림 얻기
InputStream inputStream = socket.getInputStream();
OutputStream outputStream = socket.getOutputStream();
// 클라이언트로 데이터 전송
String message = "안녕하세요, 서버님!";
outputStream.write(message.getBytes());
// 서버로부터 데이터 수신
byte[] buffer = new byte[1024];
int length = inputStream.read(buffer);
// 수신한 데이터 출력
System.out.println("서버로부터 수신한 데이터: " + new String(buffer, 0, length));
// 소켓 닫기
socket.close();
}
}
출처:
'STUDY > JAVA' 카테고리의 다른 글
[JAVA] 비어있는 문자열(String) 체크하는 방법 (0) | 2024.04.24 |
---|---|
[JAVA] e.printStackTrace to String (0) | 2024.02.21 |
[JAVA] 람다식(Lambda) (0) | 2023.11.30 |
[JAVA] 파일입출력 - File, FileInputStream, FileOutputStream (0) | 2023.11.23 |
[JAVA] Base64 인코딩, 디코딩 (0) | 2023.11.20 |