socket

Jang Seok Woo·2021년 6월 30일
0

실무

목록 보기
18/136
  1. 소켓(Socket)
    만약 네트워크와 관련된 프로젝트를 진행하면서, 사용자(User)의 관점이 아닌, 개발자(Developer)의 관점에서 네트워크를 다뤄본 경험이 있다면, "소켓(Socket)"이라는 용어가 아주 낯설게만 느껴지는 단어는 아닐 것입니다. 하지만 이제 막 정보통신학과 전공을 배우는 학생이거나 TCP/IP 통신 프로그래밍을 한번도 접해보지 못한 개발자라면, 소켓(Socket)이란 그저 벽에 뚫린 전원 케이블 연결 구멍 정도로 생각될지도 모르겠네요. (물론, 전혀 생뚱맞은 개념 이해는 아니지만...)

"소켓(Socket)"은 사전적으로 "구멍", "연결", "콘센트" 등의 의미를 가집니다. 주로 전기 부품을 규격에 따라 연결할 수 있게 만들어진 "구멍 형태의 연결부"를 일컫는 단어인데, 가정에서 흔히 볼 수 있는 콘센트 구멍을 떠올리면 쉽게 이해할 수 있을 것입니다. 다시 한번 풀어서 쓰자면, 전기를 필요로하는 디바이스 또는 부품들이 전기를 공급받을 수 있도록, 전기 공급 인프라 환경에 연결할 수 있게 만들어진 연결부가 "소켓(Socket)"인 것이죠.

네트워크 프로그래밍에서의 소켓(Socket)에 대한 의미도, 사전적 의미를 크게 벗어나지 않습니다. 프로그램이 네트워크에서 데이터를 송수신할 수 있도록, "네트워크 환경에 연결할 수 있게 만들어진 연결부"가 바로 "네트워크 소켓(Socket)"입니다.

하지만 엄밀히 따지자면, "네트워크 소켓"이라는 용어가 정확한 표현은 아닙니다. 전기 소켓이 전기를 공급받기 위해 정해진 규격(110V, 220V 등)에 맞게 만들어져야 하듯, 네트워크에 연결하기 위한 소켓 또한 정해진 규약, 즉, 통신을 위한 프로토콜(Protocol)에 맞게 만들어져야 합니다. 보통 OSI 7 Layer(Open System Interconnection 7 Layer)의 네 번째 계층인 TCP(Transport Control Protocol) 상에서 동작하는 소켓을 주로 사용하는데, 이를 "TCP 소켓" 또는 "TCP/IP 소켓"이라고 부릅니다. (UDP에서 동작하는 소켓은 "UDP 소켓"이라고 합니다.)

  1. TCP/IP 소켓 프로그래밍(Socket Programming)
    앞에서 비교적 단순한 문장으로 TCP/IP 소켓(Socket)에 대한 의미를 설명했지만, 소켓(Socket)을 사용하여 네트워크 통신 기능을 구현하는 과정, 즉, 소켓 프로그래밍(Socket Programming)은 그 개념만큼 아주 단순하지만은 않습니다. 그 이유는 바로, 소켓(Socket)으로 네트워크 통신 기능을 구현하기 위해서는, 소켓을 만드는 것과, 만들어진 소켓을 통해 데이터를 주고 받는 절차에 대한 이해가 필요하고, 운영체제 및 프로그래밍 언어에 종속적으로 제공되는 소켓 API 사용법을 숙지해야 하기 때문입니다.

그리고 덤으로, 케이블 분리로 인한 네트워크 단절, 트래픽 증가에 따른 데이터 전송 지연, 시스템 리소스 관리 문제로 인한 에러 등, 네트워크 환경에서 발생할 수 있는 다양한 예외사항에 대해서도 처리가 필요하기 때문에 소켓 프로그래밍(Socket Programming)이 초보 개발자에게는 더욱 어렵게 느껴질 수 밖에 없죠.

하지만 다행히도, 소켓 프로그래밍(Socket Programming)은 그 역사가 꽤 긴 편입니다. 거의 모든 운영체제에서 지원되고, 대부분의 프로그래밍 언어와 개발 플랫폼에서 소켓(Socket) 관련 API가 제공되고 있죠. 그리고 많은 양의 문서와 예제를, 책과 인터넷을 통해 참고할 수 있습니다.

여기서는 일단, 소켓 프로그래밍 방법을 설명하기 위해, 클라이언트 소켓(Client Socket)과 서버 소켓(Server Socket)의 역할에 대한 내용부터 살펴볼까 합니다. 데이터를 주고받기 위해서는 먼저 소켓의 연결 과정이 선행되어야 하고, 그 과정에서의 연결 요청과 수신이 각각 클라이언트 소켓과 서버 소켓의 역할이기 때문입니다.

2.1 클라이언트 소켓(Client Socket)과 서버 소켓(Server Socket)
두 개의 시스템(또는 프로세스)이 소켓을 통해 네트워크 연결(Connection)을 만들기 위해서는, 최초 어느 한 곳에서 그 대상이 되는 곳으로 연결을 요청해야 합니다. IP 주소와 포트 번호로 식별되는 대상에게, 자신이 데이터 송수신을 위한 네트워크 연결을 수립할 의사가 있음을 알리는 것이죠.

그런데, 최초 한 곳에서 무작정 연결을 시도한다고 해서, 그 요청이 무조건 받아들여지고 연결이 만들어져 데이터를 주고 받을 수 있게 될까요? 아닙니다. 한 곳에서 연결 요청을 보낸다고 하더라도 그 대상 시스템이 그 요청을 받아들일 준비가 되어 있지 않다면, 해당 요청은 무시되고 연결은 만들어지지 않습니다.

그러므로 요청을 받아들이는 곳에서는 어떤 연결 요청(일반적으로 포트 번호로 식별)을 받아들일 것인지를 미리 시스템에 등록하여, 요청이 수신되었을 때 해당 요청을 처리할 수 있도록 준비해야 합니다.

이렇듯 두 개의 시스템(또는 프로세스)이 소켓을 통해 데이터 통신을 위한 연결(Connection)을 만들기 위해서는, 연결 요청을 보내는지 또는 요청을 받아들이는지에 따라 소켓의 역할이 나뉘게 되는데, 전자에 사용되는 소켓을 클라이언트 소켓(Client Socket), 후자에 사용되는 소켓을 서버 소켓(Server Socket)이라고 합니다.

그런데 여기서, 오해하기 쉬운 내용이 있습니다. 앞서 설명한 내용을 보면 마치 클라이언트 소켓(Client Socket)과 서버 소켓(Server Socket)이 태생적으로 구조가 다른, 전혀 별개의 소켓(Socket)인 것처럼 여겨질 수 있다는 것이죠. 하지만 두 소켓(Socket)은 동일합니다. 소켓의 역할과 구현 절차 구분을 위해 다르게 부르는 것일 뿐, 전혀 다른 형태의 소켓이 아니라는 것이죠. 단지 역할에 따라 처리되는 흐름, 즉, 호출되는 API 함수의 종류와 순서들이 다를 뿐입니다.

또한 위의 그림을 보고, 소켓 연결이 완료된 다음 클라이언트 소켓과 서버 소켓이 직접 데이터를 주고 받는다고 생각하지 마시기 바랍니다. 서버 소켓은 클라이언트 소켓의 연결 요청을 받아들이는 역할만 수행할 뿐, 직접적인 데이터 송수신은 서버 소켓의 연결 요청 수락의 결과로 만들어지는 새로운 소켓을 통해 처리됩니다. 이와 관련된 내용은 지금 당장 이해되지 않더라도 너무 걱정하지 마세요. 뒤에서 좀 더 자세하게 설명할 것입니다.

2.2 소켓 API(Socket API) 실행 흐름.
자 그럼 이제 클라이언트 소켓(Client Socket)과 서버 소켓(Server Socket)이 어떻게 다루어지는지, API 호출 흐름을 통해 조금 더 자세하게 살펴보도록 하겠습니다. 일단, 각 소켓(Socket)이 처리되는 흐름을 간단한 문장으로 표현해 볼까요?

클라이언트 소켓(Client Socket)은 처음 소켓(Socket)을 [1]생성(create)한 다음, 서버 측에 [2]연결(connect)을 요청합니다. 그리고 서버 소켓에서 연결이 받아들여지면 데이터를 [3]송수신(send/recv)하고, 모든 처리가 완료되면 소켓(Socket)을 [4]닫습니다(close).

출처 : https://recipes4dev.tistory.com/153

profile
https://github.com/jsw4215

0개의 댓글