구분 | 내용 |
---|---|
프로그램명 | ircserv |
제출 파일 | Makefile, *.{h, hpp}, *.cpp, *.tpp, *.ipp, 설정 파일 |
Makefile | NAME, all, clean, fclean, re |
매개변수 | - port: listening port - password: 연결 password |
사용 가능 함수 | C++ 98에 있는 모든 함수. socket, close, setsockopt, getsockname, getprotobyname, gethostbyname, getaddrinfo, freeaddrinfo, bind, connect, listen, accept, htons, htonl, ntohs, ntohl, inet_addr, inet_ntoa, send, recv, signal, sig |
Libft 사용 가능 여부 | n/a |
설명 | C++ 98의 IRC 서버 |
C++ 98에서 IRC 서버를 만들어야 한다.
클라이언트를 만들면 안 된다.
서버 간 통신을 처리하면 안 된다.
실행 가능한 파일은 다음과 같이 실행할 수 있다:
./ircserv <port> <password>
- port: 어떤 IRC 서버가 들어오는 IRC 연결에 대해 listening을 할 지를 나타낸다.
- password: 연결 password. 서버에 연결하려는 IRC 클라이언트에게 필요하다.
- 서버는 동시에 여러 클라이언트를 다뤄야 하며, 절대로 처리 중에 멈춰선 안 된다(never hang).
- fork를 하는 것은 금지. 모든 입출력 연산은 반드시 비동기(non-blocking)여야 한다.
- 오직 한 개의
poll()
만 이러한 모든 연산(읽기, 쓰기, listen, ...)을 처리하는 데 사용할 수 있다.
❕poll()이 과제와 평가에서 언급됐더라도 select(), kqueue(), epoll() 같이 동일한 기능을 하는 다른 함수를 사용할 수 있다.
⚠️ 비동기 파일 디스크립터를 사용해야 하기 때문에,poll()
없이read/recv
나write/send
함수를 쓰는 것이 가능하고, 서버는 동기로 동작하지 않는다.
그러나 이 방식은 더 많은 시스템 자원을 소모한다.
따라서 만약read/recv
나write/send
를poll()
없이 어떤 파일 디스크립터에서 사용하려 한다면, 0점을 맞을 것이다..!
- 여러 IRC 클라이언트가 있다. 그것들 중 하나를 **레퍼런스(reference)**로 정하고, 그 레퍼런스 클라이언트는 평가 중에 사용될 것이다.
- 레퍼런스 클라이언트를 반드시 에러가 나지 않은 상태로 서버에 연결할 수 있어야 한다.
- 클라이언트와 서버 간 통신은 TCP/IP (v4 또는 v6)를 통해 이루어져야 한다.
- 서버의 레퍼런스 클라이언트를 사용하는 방법은 어떤 공식 IRC 서버와 비슷하기라도 하다면 상관 없다. 그러나, 다음과 같은 기능 정도는 구현해야 한다.
- 인증이 가능해야 한다.
레퍼런스 클라이언트로 nickname, username을 설정하고 채널에 들어가서 개인 메시지를 보내고 받을 수 있어야 한다. - 한 클라이언트로부터 채널로 보내는 메시지는 같은 재널에 있는 다른 모든 클라이언트에게 전달되어야 한다.
- 반드시
운영자(operators)
와 일반 유저가 있어야 한다. - 그리고 채널 운영자가 사용할 수 있는 명령어를 구현해야 한다.
- KICK - 클라이언트를 채널에서 퇴장시킨다.
- INVITE - 클라이언트를 채널에 초대한다.
- TOPIC - 채널의 주제를 바꾸거나 보여준다.
- MODE - 채널의 모드를 바꾼다.
- i: 비공개(Invite-only)를 설정/해제한다.
- t: 채널 운영자에게 TOPIC 명령어 제한을 설정/해제한다.
- k: 채널 password를 설정/해제한다.
- o: 채널 운영자 권한을 부여/회수한다.
- l: 채널에 인원 수 제한을 설정/해제한다.
- 인증이 가능해야 한다.
- 코드는 클린하게 작성하자!
❕ MacOS가 다른 Unix 운영체제와는 다른 방식으로
write()
를 구현했기 때문에,fcntl()
함수를 사용하는 것을 허용한다.
Unix 운영체제 중 하나와 비슷하게 동작하기 위해 파일 디스크립터를 비동기 모드로 사용해야 한다.
⚠️ 그러나fcntl(fd, F_SETFL, O_NONBLOCK);
으로만fcntl()
을 사용할 수 있다.
그 외에 다른 플래그는 금지.
명백하게 모든 가능한 에러와 이슈를 확인해라(데이터를 일부만 받는다거나, 광역대가 좁거나 기타 등등).
서버가 요청을 보낸 모든 것을 잘 처리하는지 확인하기 위해 nc
를 사용하여 다음과 같은 간단한 테스트를 해보자. :
\$> nc 127.0.0.1 6667
com^Dman^Dd
\$>
명령어를 여러 파트로 나눠서 보낼 때('com', 'man', 'd\n') ctrl + D
를 사이사이에 넣는다.
명령어를 처리하기 위해 명령어를 재구성할(rebuild) 패킷들을 가장 먼저 수신해야 한다.
더욱 실제 IRC 서버처럼 보이게 할 IRC 서버에 추가할 수 있는 부가 기능:
- 파일 전송 처리
- 봇