Windows 및 Unix 시스템 모두에서 C++로 서버를 작성하고 있습니다.push() 서버에서 select() 문제가 발생했습니다.
이 서버의 핵심 기능은 언제든지 네트워크 패킷을 수신하고 보낼 수 있어야한다는 것입니다. 특히, 서버는 메시지에 대한 응답으로 클라이언트에 데이터를 보낼 수 있어야하며 밀어 넣기시 비동기식으로 패킷을 보낼 수 있어야합니다.
위에서 설명한 시나리오에서 select()
함수를 사용하는 솔루션을 구현하는 데 어려움이 있습니다. 현재 구현 한 솔루션이 나를 전혀 설득하지 못해 더 나은 패턴/솔루션으로 구현할 수 있다고 생각합니다.
현재 서버 소켓 (새 연결 수락) 및 서버에 연결된 소켓에 대한 이벤트를 수신하여 선택을 수행하는 전용 스레드 (선택기)가 있습니다.
이 주요 선택() 루프 :
if((sel_res_ = select(nfds_+1, &read_FDs_, NULL, &excep_FDs_, &sel_timeout)) > 0){
if(FD_ISSET(serv_socket, &read_FDs_)){
//we have to handle a newly connection.
...
if(sel_res_ > 1){
//in addition to the newly connection, there is also some other message incoming on client sockets.
...
}
}else{
//we have to handle incoming messages on client sockets
...
}
}
이 솔루션은 데이터를 수신 잘 작동 및 동기 형태로 클라이언트 요청에 응답 할 수 있습니다. 그러나 서버는 비동기 데이터를 보내고 필요한 경우 패킷을 밀어 넣을 수 있어야합니다.
이렇게하려면 현재 클라이언트 소켓에서 send()
을 직접 수행하는 별도의 스레드를 사용합니다.
이 솔루션은 나를 설득하지 않으며 선택기 스레드에서 수신 및 전송하는 패킷을 중앙 집중화하려고합니다.
주요한 어려움은 성격 상으로는 select()
이 차단되어 클라이언트가 패킷을 보내지 않거나 시간 제한이 트리거 될 때까지 제어 할 수 없다는 것입니다. 제한 시간을 매우 낮게 설정하는 해결책은 나를 설득하지 못합니다. 나는 실제로 액티브 대기를하고있는 쉬운 솔루션이라고 생각한다. 그러나 푸쉬 패킷을 보내기 전에 타임 아웃 가격을 지불 할 최악의 경우는 아니다.
나는 더 우아한 해결책이라고 생각했다. 내 생각에, 잘 작동하지만 Unix/Linux 플랫폼에서만 가능합니다. 익명 파이프를 사용하여 익명 파이프 읽기 디스크립터 select()
에 삽입하려고 생각했습니다. 스레드가 푸시에서 데이터를 보내려고하면이 파이프에 무엇인가를 씁니다. select()
을 중단하고 시간을 크게 낭비하지 않고 데이터를 클라이언트에 보낼 수있는 선택기로 제어를 반환합니다. 이 시스템의 select()
기능이 실제로 소켓 인 fds에서만 작동하기 때문에 불행히도 Windows에서이 솔루션을 구현할 수 없다고 생각합니다.
그래서 질문입니다. 이런 종류의 시나리오 (Linux와 Windows 모두)를 해결하는 데 사용할 수있는 잘 알려진 해결책이 있습니까?
두 개의 스레드를 사용합니다. 하나는 읽기 용이고 다른 하나는 쓰기 용입니다. – alk