2012-12-08 5 views
0

Rant : 정말 부스트를 좋아하지 않습니다 :: asio, 그래서 대안을보고 있었고 libev를 발견했습니다. 어느 날 나를 위해 간단하게 보이지만 이해할 수없는 몇 가지 일을하고있다. 한 스레드에서 너무 많은 질문이 있으면 알려 주시기 바랍니다.libev는 제한 시간없이 소켓을 차단하도록 설정합니다.

1) 나는 NON_BLOCK에 수신 대기 소켓을 설정, 또한 소켓 (들) BLOCK에 코드에서 아직 어딘가에 NON_BLOCK 각 인정 들어오는 연결을, 회전을 설정합니다. 예는 :

void Server::MainLoop() 
{ 
    // Start infinite loop 
    while (1) { 
     ev_loop(loop, EVLOOP_NONBLOCK); 
    } 
} 

그러나 다른을 한 것 같지 않습니다 :

bool Server::Start() 
{ 
    // Setup event loop 
    loop = ev_default_loop(EVBACKEND_SELECT); //EVFLAG_AUTO ? 
    // Create Socket 
    sockfd = socket(PF_INET, SOCK_STREAM, 0); 
    addr_len = sizeof(addr) 
    // Set Socket to non blocking 
    fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFL) | O_NONBLOCK); 
    if (fcntl(sockfd, F_GETFL) & O_NONBLOCK) std::cout << "Socket is NONBLOCK" << std::endl; 
    else std::cout << "Socket is BLOCK" << std::endl; 
    if (sockfd < 0) { 
     std::cout << "ERROR opening socket" << std::endl; 
     return false; 
    } 
    bzero((char *)&addr, sizeof(addr)); 
    addr.sin_family = AF_INET; 
    addr.sin_port = htons(port); 
    addr.sin_addr.s_addr = INADDR_ANY; 
    // Bind port to socket 
    if (bind(sockfd,(struct sockaddr*)&addr, sizeof(addr))!=0) { 
     std::cout << "bind error" << std::endl; 
     return false; 
    } 
    // Listen 
    if (listen(sockfd, 2) < 0) { 
     std::cout << "listen error" << std::endl; 
     return false; 
    } 
    // Initialize and start a watcher to accepts client requests 
    ev_io_init(&w_accept, accept_cb, sockfd, EV_READ); 
    ev_io_start(loop, &w_accept); 
    return true; 
} 

또한 차단하지 메인 루프를 만들기 위해 노력했다. 제발 내가 그것을 읽었습니다 설명서 (인터넷에서 유일하게 사용할 수있는 문서 소스)로 리디렉션하지 마십시오. 그러나 내 읽기 콜백이 실행될 때마다, 소켓이 마술

2를 차단하도록 설정되어

void accept_cb(struct ev_loop *loop, struct ev_io *watcher, int revents) 
.... 
c->client_sd = accept(watcher->fd, (struct sockaddr *)&c->client_addr, &c->client_len); 
.... 
ev_io *w_client = (struct ev_io*) malloc (sizeof(struct ev_io)); 
ev_io_init(w_client, read_cb, c->client_sd, EV_READ); 
ev_io_start(loop, w_client); 
fcntl(watcher->fd, F_SETFL, fcntl(watcher->fd, F_GETFL) | O_NONBLOCK); 

) 제가 설정을 시도했다 :

I 허용 된 클라이언트 소켓이 작업을 수행 소켓에 대한 타임 아웃 : struct timeval timeout; (여기에서 촬영 : this question)

timeout.tv_sec = 10; 
timeout.tv_usec = 0; 

if (setsockopt (sockfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, 
      sizeof(timeout)) < 0) 
    error("setsockopt failed\n"); 

if (setsockopt (sockfd, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, 
      sizeof(timeout)) < 0) 
    error("setsockopt failed\n"); 

그것은 단순히 작동하지 않습니다. 소켓이 블로킹 모드로 재설정 되었기 때문입니까?

3) libev 용 C++ 래퍼를 보았습니다. 나는 콜백 함수를 정적 함수로 만들어야한다는 사실을 절대 싫어한다. 그러나 모든 예제는 내가 본 사용 :

signal.loop.break_loop(); 

와 충분히 재미있게 생산,

loop.run(0); 

:

error: ‘struct ev::loop_ref’ has no member named ‘break_loop’ error: ‘struct ev::default_loop’ has no member named ‘run’

데비안 짜기에.

그래서, 내가 무엇을 해달라고 부탁하는 것입니다 :

  1. 는 어디 소켓 블록에 NON_BLOCK 무엇을 변경 누구?
  2. (차단 또는 비 차단) 소켓에 대한 시간 제한을 설정할 수있는 방법 (차단 또는 비 차단)
  3. ev ++. h의 문제점과 내가 사용할 수없는 래퍼를 사용하는 멋진 사람들이있는 이유는 무엇입니까?

소켓을 사용하여 데이터를 읽고 보낼 수 있지만 차단하지 않고 시간 제한없이 사용할 수 있습니다. 게다가 이것은 서버이기 때문에 연결된 클라이언트마다 메시지를 저장해야하므로 코드를 클래스로 유지해야했습니다. 이 정적 또는 비 클래스 방법을 단순히 파멸 시키거나 매우 다른 접근 방식을 강요합니다.

추 신 : libev에 대한 대안은 무엇입니까?

+0

소켓을 블로킹으로 다시 설정하는 libev 소스 코드에는 아무 것도 없습니다. 어떻게 결정합니까? 하지만 코드에서 watcher-> fd가 새로 허용 된 소켓 대신 비 차단으로 설정되어 있습니다. – nos

+0

Boost.Asio는 libev에 대한 환상적인 대안이지만 이미 좋아하지는 않는다고 언급했습니다. 아마도 당신은 우려를 다른 질문으로 확장시킬 수 있습니까? –

+0

@SamMiller 나는 그것을 여러 번 사용하려고 노력해 왔으며, 내가 필요로하는 것이 너무 복잡하고 복잡하다고 생각된다. 나는 물건을 간단하게 유지하고 싶다. –

답변

3

클라이언트 FD를 비 차단 모드로 설정하지 않습니다. 청취 소켓 FD를 설정 중입니다.

+1

맞다 :'c-> client_sd'가 아니라' 'fcntl' 호출에서 watcher-> fd'를 호출합니다. –

+0

고마워, 나는 이것에 너무 화가났다. 나는 그것을 발견하지 못했다! –