[42서울] 소켓 통신과 IRC

tamagoyakii·2023년 2월 28일
0

42seoul

목록 보기
16/19
post-thumbnail

소켓 통신

TIL 38일차 - [네트워크] OSI 7 계층

네트워크에 대한 내용을 복습하고 해당 과제를 진행하면 좋을 것 같다.

소켓(socket)

소켓은 두 개의 프로그램이 양방향 통신을 할 때 사용되는 통로 양 끝의 엔드 포인트다. 여기서 엔드 포인트는 IP 주소와 포트 번호의 조합을 의미한다.

소켓 통신은 서버와 클라이언트 간의 양방향 통신으로, 클라이언트도 서버로 요청을 보낼 수 있고 서버도 클라이언트에 요청을 보낼 수 있다. 보통 실시간 스트리밍이나 실시간 채팅 등 지속적인 연결이 필요한 경우에 사용된다.

클라이언트가 서버에 요청을 보내고 서버가 응답하는 방식의 HTTP(Hyper Text Transfer Protocol)은 단방향 통신이기 때문에 실시간으로 데이터를 주고받기에 적합하지 않지만, 소켓 통신은 계속해서 connection을 가지고 있기 때문에 실시간 통신에 적합하다. 하지만 HTTP 통신에 비해 많은 자원을 소모한다는 단점은 있다.

소켓은 TCP/IP 프로토콜을 이용하는 소켓(스트림)과 UDP 프로토콜을 이용하는 소켓(데이터그램)으로 구분된다. TCP/IP 소켓은 신뢰성 있는 데이터 전송을 위해 연결 지향적(Connection-Oriented)으로 동작하며, UDP 소켓은 비연결형(Connectionless)으로 동작한다.

소켓을 이용하여 데이터를 주고받기 위해서는 서버와 클라이언트 모두에서 소켓을 생성하고, 소켓 주소 및 포트 번호를 설정해야 한다.

포트 바인딩

포트(Port)는 네트워크 상에서 통신하기 위해 호스트 내부에서 프로세스가 할당받는 고유한 번호다. 즉, 같은 호스트 내에서 서로 다른 프로세스가 같은 포트 번호를 가지고 있을 수 없다.

포트 바인딩은 위와 같은 네트워크 환경에서 특정 포트 번호를 사용하는 프로세스를 지정하는 작업이다. 네트워크에서 데이터를 주고받으려면, 각 프로세스가 네트워크로 연결되어야 한다. 이를 위해 포트 번호가 할당되며, 포트 번호를 바인딩 하면 해당 포트 번호를 사용하는 프로세스를 구체적으로 지정할 수 있다.

보안 측면에서, 포트 바인딩은 불필요한 포트를 열어놓지 않도록 하는 것이 중요하다. 바인딩 되지 않은 포트는 보안 취약점이 될 수 있으므로, 서비스를 사용하지 않는 포트는 필요에 따라 차단해야 한다.

또, 사용하고자 하는 포트가 이미 다른 네트워크에서 사용되고 있지 않은지 확인하는 작업이 필요하다. 이미 점유된 포트는 사용할 수 없기 때문에 이런 이유로 포트 바인딩에 실패한다면 예상치 못한 에러가 발생할 수 있다.

서버와 클라이언트

소켓 통신에서 서버와 클라이언트가 통신하는 대략적인 순서는 다음과 같다.

  1. 서버가 소켓을 생성(socket())하고, 특정 포트에 바인딩(bind())하여 클라이언트의 접속을 기다린다.(listen())
  2. 소켓을 non-blocking 모드로 설정한다.
  3. 클라이언트가 소켓을 생성(socket())하고, 서버에 접속(connect())을 시도한다.
  4. 서버는 클라이언트의 접속 요청을 받아들이고(accept()), 연결된 새로운 소켓을 생성한다.
  5. 클라이언트와 서버 간의 데이터 전송이 이루어진다(read()/write()). 데이터는 TCP 프로토콜을 사용하여 전송된다.
  6. 클라이언트 또는 서버 중 한쪽이 소켓 연결을 종료(close())하면, 상대의 소켓도 종료된다.

서버는 특정 포트에 바인딩 하여 클라이언트를 기다린다. 해당 포트로 클라이언트가 접근하면 포트는 가지고 있던 소켓을 클라이언트와 소통하기 위해 사용하고, 새로운 소켓을 열어 서버와 소통하게 된다.

IRC(internet relay chat)

IRC는 1988년 핀란드에서 개발된 실시간 인터넷 채팅 프로토콜로, TCP 기반의 소켓 인터페이스를 사용한다.

IRC 프로토콜은 트리 구조의 서버 네트워크를 지원한다. 하지만 ft_irc는 서버 간의 커뮤니케이션을 구현하지 않아도 되기 때문에 트리 구조를 직접 구현할 필요는 없는 것 같다.

-> IRC rfc

rfc 문서는 국제 인터넷 표준화 기구(IETF, Internet Engineering Task Force)에서 제공하고 관리하는 문서 형식이다. IRC는 인터넷 표준으로 규정되지 않았기 때문에 rfc 문서로 작성된 위의 문서를 참고하여 구현해야 한다.

IRC에서 채널은 여러 사용자가 동시에 대화를 나눌 수 있는 공간이다. 때문에 위의 문서에는 채널 생성, 채널 모드 설정, 사용자 목록 관리 등에 대해 설명이 있다.

IRC 메시지는 "커맨드(Command) + 매개변수(Parameters)"의 형식을 따르며, 클라이언트는 이 형식을 사용하여 IRC 서버와 상호작용해야 한다. 우리가 구현하기로 결정한 주요 명령어는 다음과 같다. 자세한 내용은 다음 포스팅에서 다루도록 하겠다.

PASS : 서버에 연결하기 위한 패스워드를 확인한다.
NICK : 닉네임을 변경한다.
USER : 유저 이름을 변경한다.
JOIN : 채널에 입장한다.
PART : 채널에서 나간다.
PRIVMSG : 특정 사용자 또는 채널에 메시지를 보낸다.
NOTICE : 서버의 유저에게 메시지를 보낸다.
LIST : 현재 서버에서 사용 가능한 채널 목록을 조회한다.
PING : 클라이언트-서버 간의 연결을 확인한다.
OPER : 관리자 권한을 얻는다.
KICK : 유저를 특정 채널에서 내보낸다.
QUIT : IRC 서버에서 나간다.

ft_irc는 서버를 구현하는 과제기 때문에 만들어져 있는 클라이언트 중 하나를 선택하여 사용하면 된다. 우리는 클라이언트 간의 파일 전송을 처리해주는 irssi를 사용하기로 했다.

0개의 댓글