네트워크 통신/Boost

Boost.asio 소켓 연결 수락

마달랭 2024. 11. 7. 23:40
반응형

개요

클라이언트에서 서버에게 요청 연결을 요청하였다면 서버에서 해당 요청을 수락할 수 있다.

다만, 요청을 수락하기 전에 처리해야 할 일이 있으며, 준비가 되지 않았다면 운영체제에서 모든 요청을 거절한다.

 

먼저 서버 프로그램은 수용자 소켓을 만들고 연 후, 특정 종료점에 바인딩 해야한다.

이때 까지 클라이언트가 보내는 연결 요청은 모두 운영체제에서 거절하게 된다.

클라이언트의 연결 요청을 받아들이기 위해선 바인딩을 마친 후 리스닝 상태가 되어야 한다.

리스닝 상태가 되면 운영체제에서는 클라이언트의 요청을 큐에 저장하고, 연결 요청을 받아들이기 시작한다.

 

 

연결 수락 과정

  1. 새 연결 요청이 도착하면 먼저 운영체제가 받는다.
  2. 해당 메시지는 연결 요청이 가리키는 수용자 소켓의 대기열에 들어간다.
  3. 대기열에 있는 연결 요청은 서버 프로그램이 처리하게 된다.
  4. 서버 프로그램이 다음 요청을 처리할 수 있다면 큐에서 요청을 꺼내 처리한다.

 

연결 듣기

  1. 서버가 들어오는 연결 요청을 받을 포트 번호를 초기화 한다.
  2. 서버의 종료점을 만든다
  3. 수용자 소켓을 인스턴스화 하고 연다.
  4. 2번에서 만든 서버 연결 종료점에 수용자 소켓을 바인딩한다.
  5. 수용자 소켓의 listen() 메서드를 호출하여 연결 요청이 있는지 리스닝 상태가 되도록 한다.
  6. 능동 소켓 객체를 인스턴스화 한다.
  7. 연결 요청을 처리할 준비가 되면, 위에서 생성한 능동 소켓 객체를 인자로 전달해 accept() 메서드를 호출한다.
  8. 이 호출이 성공하면 클라이언트 프로그램과 연결되어 통신이 가능하다.
#include <boost/asio.hpp>
#include <iostream>

using namespace boost;

int main()
{
	// 대기열 큐의 최대 크기 정의
	const int BACKLOG_SIZE = 30;

	// Step 1. 서버 프로그램이 사용할 포트 번호
	unsigned short port_num = 3333;

	// Step 2. 서버의 종료점을 만든다(any() 사용)
	asio::ip::tcp::endpoint ep(asio::ip::address_v4::any(),
		port_num);

	// io_service 인스턴스 생성
	asio::io_service ios;

	try {
		// Step 3. 수용자 소켓을 인스턴스화 하고 연다.
		asio::ip::tcp::acceptor acceptor(ios, ep.protocol());

		// Step 4. 수용자 소켓을 ep에 바인드 한다.
		acceptor.bind(ep);

		// Step 5. 수용자 소켓을 리스닝 상태로 만든다.
		acceptor.listen(BACKLOG_SIZE);

		// Step 6. 능동 소켓을 생성한다.
		asio::ip::tcp::socket sock(ios);

		// Step 7. 연결 요청을 수락하고 클라이언트에 능동 소켓을 연결한다.
		acceptor.accept(sock);

		// 이 시점까지 catch문이 실행되지 않았다면 클라이언트와 통신할 준비가 완료되었다.
	}
	catch (system::system_error& e) {
		std::cout << "Error occured! Error code = " << e.code()
			<< ". Message: " << e.what();

		return e.code().value();
	}

	return 0;
}

 

서버 프로그램이 실행되고 리스닝 상태까지 진행되었다면, 무한루프에 걸린 듯 클라이언트 요청을 쭉 대기하는 상태가 된다.

 

 

 

참고

수용자 소켓은 연결 요청을 처리할 뿐, 자신이 클라이언트 프로그램에 연결되는 것이 아니다.

또 다른 능동 소켓을 열어 클라이언트 프로그램과 통신할 수 있도록 연결한다.

수용자 소켓은 리스닝 상태에서 연결 요청이 있을 경우 수용해 줄 뿐이다.

 

UDP 프로토콜에서는 연결 수립이 없으므로 수용자 소켓을 사용하지 않는다.

그 대신 능동 소켓을 연결점에 바인딩하여 들어오는 I/O 메시지가 있는지 들을 수 있다.

이땐 능동 소켓을 바인딩 하고 리스닝 상태로 만들어 준 뒤 연결 요청이 있다면 즉시 통신하면 된다.

 

 

728x90
반응형

'네트워크 통신 > Boost' 카테고리의 다른 글

Boost.asio I/O 고정 크기 버퍼  (0) 2024.11.08
Boost.asio I/O 연산  (0) 2024.11.08
Boost.asio 소켓 연결 요청  (2) 2024.11.07
Boost.asio 소켓 바인딩  (0) 2024.11.07
Boost.asio DNS 이름 해석하기  (1) 2024.11.07