🍭
webserv
  • Webserv tutorials
  • 학습 | 웹(Web)
  • 학습 | 웹서버(Webserver)
  • 학습 | HTTP 개요
  • 학습 | 리퀘스트(Request)
  • 학습 | 리스펀스(Response)
  • 학습 | CGI
  • 학습 | RFC
  • 학습 | 소켓과 TCP 커넥션
  • 학습 | 서브젝트(Mandatory)
  • 실습 | 서버 프로그램
  • 실습 | 클라이언트 프로그램
  • 실습 | 통신 테스트
  • 실습 | telnet
  • 실습 | nginx
  • 설계 | 설계의 중요성
  • 설계 | 플로우차트
  • 설계 | 설정 파일
  • 설계 | 객체 설계
  • 설계 | 팀 코드 컨벤션
  • 설계 | 클래스 명세서
  • 설계 | 협업환경 구성
  • 구현 | 메인함수
  • 구현 | 서버생성
  • 구현 | Select
  • 구현 | 서버제어
  • 구현 | 요청 읽기
  • 구현 | 메소드 실행하기
  • 구현 | 응답 생성하기
  • 구현 | CGI 실행하기
  • 구현 | 응답 보내기
  • 구현 | 주요 메소드
  • 구현 | Libft
  • 구현 | 구현 테크닉 16
  • 구현 | 로그
  • 테스트 | Postman
  • 테스트 | Tester
  • 테스트 | 브라우저
  • 테스트 | Siege
  • 보너스 파트
  • 학습 레퍼런스
  • 튜토리얼을 끝내며
Powered by GitBook
On this page

Was this helpful?

구현 | Select

이 서브젝트에서 가장 중요한 함수 중 하나가 바로 Select입니다. 좌측의 학습 레퍼런스에서 Select에 관한 아티클들을 가능한 많이 읽는 것을 추천합니다. fd_set이라는 게 무엇인지, 어떻게 생겼는지, select 함수를 실행했을 때 어떤 일이 일어나는지, 함수 실행 후 read fd_set에, write fd_set에 특정 fd의 bit가 1로 설정되어 있다는 것이 무엇을 의미하는지, timeout 인자에 따라 동작이 어떻게 달라지는지 등에 대한 학습이 먼저 선행되어야 합니다.

코드는 아래와 같습니다. fd_set은 select 함수를 실행하면 내용이 바뀌기 때문에 backup해두었던 data를 인자로 넘길 data에 copy하는 작업을 먼저 실행하고, select 함수를 실행해 요청을 보내거나 응답을 받을 준비가 된 클라이언트가 있다면 서버들을 한 번씩 실행시키고, 서버의 오래된 커넥션들을 제거합니다. 이런 작업들로 인해 클라이언트들의 소켓 fd가 변경될 수 있으므로, select를 통해 감시할 fd의 범위를 다시 잡아줍니다. ctrl+c와 같은 signal이 들어와 반복문의 조건(g_live)이 false가 되기 전까지는 이 과정을 무한히 반복합니다.

void
ServerManager::runServer()
{
	signal(SIGINT, changeSignal);

	timeval timeout;
	timeout.tv_sec = 0;
	timeout.tv_usec = 0;

	g_live = true;
	resetMaxFd();
	while (g_live)
	{
		int cnt;
		fdCopy(ALL_SET);

		if ((cnt = select(this->m_max_fd + 1, &this->m_read_copy_set, &this->m_write_copy_set, \
		NULL, &timeout)) == -1)
		{
			perror("Server select error: ");
			ft::log(ServerManager::log_fd, "[Failed][Function]Select function failed(return -1)");
			throw std::runtime_error("select error");
		}
		else if (cnt == 0)
			continue ;
		writeServerHealthLog();
		for (std::vector<Server>::iterator it = m_servers.begin() ; it != m_servers.end() ; ++it)
		{
			it->run();
			closeOldConnection(it);
		}
		resetMaxFd();
	}
	exitServer("server exited.\n");
}

fdSet, fdIsset, fdClr, fdZero 등의 fd_set을 조작하는 함수들은 모두 직접 작성하여야 합니다.

Select 함는 소스 전체를 통틀어 1개만 있어야 합니다.

Previous구현 | 서버생성Next구현 | 서버제어

Last updated 4 years ago

Was this helpful?