Network

[Network] 포트(Port)와 소켓(Socket)

코냥이 2024. 3. 19. 22:25

 

💭 포트(Port)란?


포트(Port)
: 하드웨어 측면에서 포트는 통신 장비를 연결하기 위한 연결단을 의미하고,
소프트웨어 측면에서 포트는 네트워크 서비스를 식별하는 논리적 단위를 의미한다.
  • OSI 7 계층 중 데이터 링크 계층에서 Mac 주소로 식별하고, 네트워크 계층에서 IP 주소를 통해 목적지에 간 후, 어떤 프로세스가 데이터를 받을지 포트 번호로 구분한다.
  • IP 주소 뒤에 콜론(:)을 붙이고 포트를 적어준다.
    • Ex) 127.0.0.1:8080

 

포트(Port)의 필요성

택배 기사님이 구매자의 아파트 주소는 알고 있지만, 아파트 몇 호에 사는지 모른다면 구매자에게 택배를 전달하지 못하는 상황이 발생한다.

포트가 아파트 호수 역할을 한다고 이해하면 쉽다.

네트워크 통신을 할 때 해당 IP 서버가 존재하는 컴퓨터에 접근을 한다. 보통 하나의 컴퓨터에는 여러 프로그램이 동시에 실행되고 있기 때문에 어느 프로그램에 접속할 건지 정확하게 알려줘야 한다. 이때 필요한 것이 포트이다. 포트가 없다면, 데이터가 정확히 어디로 전달되어야 하는지 모르는 상황이 발생된다. 

 

 

 

포트(Port)의 종류

포트는 크게 3종류로 구분된다.

 

1. Well-Known Port (잘 알려진 포트) : 0번 ~ 1023번
2. Registered Port (등록된 포트) : 1024번 ~ 49151번
3. Dynamic Port (동적 포트) : 49152번 ~ 65535번

 

 

✔️ Well-Known Port (잘 알려진 포트)

Well-Known Port는 특정 용도로 사용하기 위해 IANA(Internet Assigned Numbers Authority)에서 정한 포트이다.

포트 번호 프로토콜 용도
20 FTP 데이터 전송 포트
21 FTP 제어 포트
22 SSH Secure SHell
23 Telnet 암호화되지 않은 텍스트 통신
25 SMTP 이메일 전송 프로토콜
53 DNS Domain Name System
80 HTTP 웹 페이지 전송 프로토콜
123 NTP Network Time Protocol 시간 동기화 프로토콜
443 HTTPS Hyper Text Transfer Protocol over Secure sockets
514 Syslog 시스템 로그 전송 프로토콜

 

 

✔️ Registered Port (등록된 포트)

Registered Port는 IANA에 포트 등록을 요청하여 특정 서비스에서 사용하는 포트이다.

 

 

✔️ Dynamic Port (동적 포트)

Dynamic Port는 서버와 클라이언트가 연결될 때 동적으로 생성되는 포트로, 특정 용도가 지정되어 있지 않다.

 

 

 

 

 

💭 소켓(Socket)이란?


소켓(Socket)
: 네트워크 상에서 데이터를 주고 받기 위한 통로를 제공하는 인터페이스이다.
  • 소켓 프로그래밍(Socket Programming) - 소켓 연결 방식을 사용하여 프로그래밍하는 것으로, 서버(Server)와 클라이언트(Client)가 특정 포트(Port)를 통해 연결 유지가 되어 실시간으로 양방향 통신을 하는 방식이다.
  • 소켓은 OSI 7계층 중 전송 계층과 응용 계층 사이에 존재하는 인터페이스이다.
    • 통신의 시작점과 종료점

 

 

소켓 통신

두 개의 프로세스가 소켓을 통해 네트워크 연결을 할 때, 클라이언트(Client) 소켓서버(Server) 소켓의 역할로 나누어진다.

소켓 통신 과정

 

클라이언트 소켓 통신 과정은 다음과 같다.

1. 클라이언트 소켓이 소켓을 생성한다. : socket()
2. 클라이언트 소켓이 서버 소켓에 연결 요청을 보낸다. : connect()
3. 서버 소켓이 연결 요청을 받으면 데이터 송/수신이 이루어진다. : send() , recv()
4. 모든 송/수신이 이루어지면 소켓을 닫는다. : close()

 

✔️ 1. 클라이언트 소켓이 소켓을 생성한다.

소켓을 생성할 때 TCP 통신을 위한 스트림(Stream) 타입이나 UDP 통신을 위한 데이터그램(Datagram) 타입과 같은 소켓 타입을 지정할 수 있다.

최초 소켓이 생성될 때는 연결 대상에 대한 아무런 정보가 없고, 말 그대로 socket() API를 호출하여 소켓만 생성한다.

 

✔️ 2. 클라이언트 소켓이 서버 소켓에 연결 요청을 보낸다.

소켓을 생성한 후, IP 주소와 포트 번호를 통해 connect() API를 호출하여 연결 요청을 보낸다.

connect() API는 연결 요청에 대한 결과가 정해지기 전까지 종료되지 않는 블록(Block) 방식으로 동작한다.

connect() API 호출이 성공되면 send()와 recv() API를 통해 데이터를 송/수신할 수 있게 된다.

 

✔️ 3. 서버 소켓이 연결 요청을 받으면 데이터 송/수신이 이루어진다.

send() API는 데이터 보내는 역할, recv() API는 데이터를 받는 역할을 한다.

send(), recv() API도 마찬가지로 블록 방식으로 동작한다.

 

✔️ 4. 모든 송/수신이 이루어지면 소켓을 닫는다.

모든 데이터의 송/수신이 완료되면 close() API를 호출하여 소켓을 닫는다.

close() API로 닫힌 소켓은 더 이상 유효한 소켓이 아니기 때문에 다시 통신하고 싶으면 1번 ~ 3번 과정을 거쳐야 한다.

 

 

 

 

서버 소켓 통신 과정은 다음과 같다.

1. 서버 소켓이 소켓을 생성한다. : socket()
2. 서버 소켓이 사용할 IP 주소와 포트 번호를 생성한 소켓에 결합시킨다. : bind()
3. 클라이언트 소켓으로부터 연결 요청이 수신되는지 대기한다. : listen()
4. 수신된 요청을 받으면 데이터 통신을 위한 소켓을 생성한다. : accept()
5. 연결되면 데이터 송/수신이 이루어진다. : send() , recv()
6. 데이터 송/수신이 완료되면 소켓을 닫는다. : close()

 

 

✔️ 1. 서버 소켓이 소켓을 생성한다.

클라이언트 소켓과 마찬가지로, 소켓 연결을 위해 socket() API를 호출하여 소켓을 생성한다.

 

✔️ 2. 서버 소켓이 사용할 IP 주소와 포트 번호를 생성한 소켓에 결합시킨다.

bind() API를 호출하여 소켓에 IP 주소와 포트 번호를 바인딩(Binding)한다.

만약, 소켓이 사용하는 포트가 다른 소켓의 포트와 중복된다면 데이터를 수신할 때 어떤 소켓이 처리해야 하는지 모르는 문제가 발생된다.

그렇기 때문에 해당 소켓에 지정된 포트 번호를 사용할 것을 알려주는 바인딩 과정이 필요한 것이다. 지정된 포트를 다른 소켓이 사용하고 있다면 bind() API에서 에러가 return 된다.

 

✔️ 3. 클라이언트 소켓으로부터 연결 요청이 수신되는지 대기한다.

바인딩 과정을 마치면, 서버 소켓은 클라이언트의 요청을 수신할 준비가 완료된 것이다.

이제 listen() API를 호출하여 클라이언트 소켓의 요청을 대기한다.

 

✔️ 4. 수신된 요청을 받으면 데이터 통신을 위한 소켓을 생성한다.

accept() API를 통해 소켓 간의 연결이 이루어진다. 이 때 주의할 점은 1번 ~ 3번 과정에서 사용한 서버 소켓이 아니라는 점이다 !!

accept() API 내부에서 새로 만들어진 소켓이다.

 

✔️ 5. 연결되면 데이터 송/수신이 이루어진다.

send(), recv() API를 호출하여 클라이언트 소켓의 데이터 송/수신 과정과 동일한 방식으로 이루어진다.

 

✔️ 6. 데이터 송/수신이 완료되면 소켓을 닫는다.

close() API를 호출하여 클라이언트 소켓과 동일한 방식으로 소켓을 닫는다.

 

 

 

 

 

 

 

 

출처

 

 

 

긴 글 읽어주셔서 감사합니다 🍀

잘못 작성된 내용은 피드백 주시면 반영하겠습니다 😎