블로킹 소켓 서버를 비 블로킹 버전으로 다시 쓰는 데 문제가 있습니다. 사실, 나는 소켓을 더 이상 연결하지 못하는 것 같아요, 나는 오늘의 대부분을 인터넷 검색하고, 내가 여기 저기에있는 다른 해결책을 시도했지만, 아무도 제대로 작동하지 않는 것 같습니다 ... 현재 내 서버 루프는 새로운 소켓을 수락하지 않고 select() 호출 시간 초과를 유지합니다. 클라이언트 소켓이 어떤 수준에서 연결하는 것 같습니다. 시작하면 쓰기를 차단하고 서버를 닫으면 연결이 피어에 의해 재설정되었음을 알립니다.* nix & C++ 비 블로킹 소켓 서버 작성하기
올바른 가정은 다음과 같습니까? 비 블로킹 서버의 경우 일반적으로 소켓을 열고 비 블로킹 플래그를 설정하고 바인드하고 읽기 파일 설명자를 호출하기 시작한 다음 채워지기를 기다려야합니까? 끝내 대기중인 이전 차단 "accept()"호출을 제거해야합니다. 수락 호출을 시도하면 지금 -1이됩니다 ...
다음은 내가 시도하는 관련 코드입니다. 당신은 전체 루프를 표시하지 않기 때문에 지금
fd_set incoming_sockets;
....
int listener_socket, newsockfd, portno;
socklen_t clilen;
struct sockaddr_in serv_addr, cli_addr;
....
listener_socket = socket(AF_INET, SOCK_STREAM, 0); //get socket handle
int flags = fcntl(listener_socket, F_GETFL, 0);
if(fcntl(listener_socket, F_SETFL, flags | O_NONBLOCK) < 0)
log_writer->write_to_error_log("Error setting listening socket to non blocking", false);
memset(&serv_addr, 0, sizeof(struct sockaddr_in));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno);
....
if (bind(listener_socket, (struct sockaddr *) &serv_addr,
sizeof(struct sockaddr_in)) < 0)
{
log_writer->write_to_error_log("Unable to bind socket, aborting!", true);
}
....
struct timeval timeout;
timeout.tv_sec = 1;
timeout.tv_usec = 0;
int ready_sockets = 0;
listen(listener_socket,1);
FD_ZERO(&incoming_sockets);
FD_SET(listener_socket, &incoming_sockets);
while(true)
{
ready_sockets = select(listener_socket + 1 , &incoming_sockets, (fd_set *) 0, (fd_set *) 0, &timeout );
if(ready_sockets == 0)
{
//I loop here now for ever
std::cout << "no new sockets available, snooze 2\n";
sleep(2);
} else
{
std::cout << "connection received!\n";
오류에 대해서는'select'의 반환 값을 실제로 확인해야합니다. 지금 당장은 문제가되지 않을 수도 있지만 장래에있을 수 있습니다. 그 외에는 코드에서 명백한 오류를 볼 수 없습니다. –
안녕하세요, 요아킴, 답장을 보내 주셔서 감사합니다! 실제로 다른 값도 확인합니다 (0보다 작은 경우).하지만 지금은 == 0으로 유지하고 있기 때문에 가독성을 위해 생략했습니다. – julumme