유 닉 스 에서 SCTP socket 기반 통신: I / O 재 활용 실현

1. 장면 수요
최근 에 작은 프로그램 을 써 서 SCTP 연결 과정 에서 의 행동 을 검증 합 니 다.
  • 프로그램 은 서버 엔 드 와 클 라 이언 트 엔 드 로 나 뉜 다.
  • 두 프로그램 모두 상대방 의 데 이 터 를 감청 하 는 동시에 사용자 의 키보드 입력 을 감청 할 수 있어 야 한다 (사용 자 는 상대방 에 게 메 시 지 를 보 내 거나 응용 프로그램 을 내 놓 을 지 여 부 를 제어 할 수 있다).

  • 2. 해결 방안
    2.1 다 중 스 레 드
    첫 번 째 로 생각 나 는 해결 방법 은 다 중 스 레 드 입 니 다.
  • 감청 사용자 가 하나의 라인 을 입력 하여 감청 표준 입력 을 막는다.
  • socket 의 소식 을 감청 하 는 것 도 감청 을 막 는 것 이다.

  • 이렇게 실 현 된 응용 프로그램 에는 약간의 폐단 이 있다
  • 다 중 스 레 드 는 반드시 스 레 드 전환 에 추가 비용 을 가 져 올 것 이다.
  • 스 레 드 가 서로 끊 길 수 있 기 때문에 프로그램 을 설계 할 때 서로 배척 하 는 것 을 고려 해 야 한다.
  • 콘 솔 의 알림 정보 가 인쇄 되 지 않 습 니 다
  • 2.2 Poll 함 수 를 사용 하여 I / O 재 활용 실현
    다행히 우 리 는 Poll 함수 가 있어 서 I / O 재 활용 을 실현 할 수 있 습 니 다. 그러면 우 리 는 두 개의 스 레 드 를 하나 로 합성 할 수 있 습 니 다.단일 스 레 드 에서 표준 입력 과 sctp socket 을 동시에 감청 하고 먼저 IO 재 활용 클래스 를 실현 합 니 다.
    class IoMultiplex
    {
    public:
    ...
        void RegisterFd(int fd, CallBack cb);
        void Poll();    
    private:
        void PollEventHandler();
        
        std::vector poll_items;
        std::vector cb_lists;
    };
    

    2.2.1 IoMultiplex 멤버 함수
    첫 번 째 멤버 함 수 는 RegisterFd 입 니 다. 호출 자 에 게 새 파일 설명 자 를 등록 하 는 데 사 용 됩 니 다. (예 를 들 어 socket 파일 설명 자) 와 그 에 상응하는 반전 함수 입 니 다.
    void IoMultiplex::RegisterFd(int fd, CallBack cb)
    {
        pollfd item;
        item.fd = fd;
        item.events = POLLIN;
        poll_items.push_back(std::move(item));
        
        cb_lists.push_back(std::move(cb));
    }
    

    서로 다른 poll 이 벤트 는 구성원 변수 에 저장 되 며, 이 이벤트 에 대응 하 는 리 셋 함 수 를 일일이 저장 합 니 다.
    두 번 째 구성원 함 수 는 Poll 입 니 다. 호출 자 에 게 poll 과정 을 시작 하 는 데 사 용 됩 니 다. poll 은 차단 함수 호출 입 니 다.
     void IoMultiplex::Poll()
    {
        switch(poll(poll_items.data(), poll_items.size(), -1))
        {
            ...
            default:
                PollEventHandler();
                // new message
                break;
        }
    }
    

    단일 스 레 드 프로그램 은 poll 함수 에 막 혀 등록 이벤트 가 발생 하 기 를 기다 리 고 새로운 이벤트 가 발생 하면 등 록 된 리 셋 함 수 를 호출 합 니 다.
    2.2.2 표준 입력 감청 실현
    표준 입력 한 파일 설명 자 는 0 입 니 다.
    io_multi->RegisterFd(STDIN, [this](int fd)
              { ReadUserCmd(fd); });
    

    ReadUserCmd 는 사용자 의 입력 을 읽 고 해당 동작 을 수행 합 니 다.
    2.2.3 이벤트 SCTP 소켓 감청
    io_multi->RegisterFd(sock_op->socket_fd(), [this](int fd)
                { SctpMsgHandler(fd); });
    

    3 폴 이벤트
    폴 이 감청 할 수 있 는 사건 은 폴 린 뿐만 아니 라 다음 과 같다.
    #define POLLIN      0x0001
    #define POLLPRI     0x0002
    #define POLLOUT     0x0004
    #define POLLERR     0x0008
    #define POLLHUP     0x0010
    #define POLLNVAL    0x0020
    
  • POLLIN: 데이터 읽 기 가 있 습 니 다.
  • POLLPRI: 읽 을 긴급 데이터 가 있 습 니 다.예 를 들 어 TCP socket 의 out - of - band 데이터
  • POLLOUT: 데이터 가 적 혀 있 습 니 다.
  • POLLERR: 오류;
  • POLLHUP: 끊 기;
  • POLLNVAL: 불법 요청: fd 가 열 리 지 않 았 습 니 다.
  • 좋은 웹페이지 즐겨찾기