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’
데비안 짜기에.
그래서, 내가 무엇을 해달라고 부탁하는 것입니다 :
- 는 어디 소켓 블록에 NON_BLOCK 무엇을 변경 누구?
- (차단 또는 비 차단) 소켓에 대한 시간 제한을 설정할 수있는 방법 (차단 또는 비 차단)
- ev ++. h의 문제점과 내가 사용할 수없는 래퍼를 사용하는 멋진 사람들이있는 이유는 무엇입니까?
소켓을 사용하여 데이터를 읽고 보낼 수 있지만 차단하지 않고 시간 제한없이 사용할 수 있습니다. 게다가 이것은 서버이기 때문에 연결된 클라이언트마다 메시지를 저장해야하므로 코드를 클래스로 유지해야했습니다. 이 정적 또는 비 클래스 방법을 단순히 파멸 시키거나 매우 다른 접근 방식을 강요합니다.
추 신 : libev에 대한 대안은 무엇입니까?
소켓을 블로킹으로 다시 설정하는 libev 소스 코드에는 아무 것도 없습니다. 어떻게 결정합니까? 하지만 코드에서 watcher-> fd가 새로 허용 된 소켓 대신 비 차단으로 설정되어 있습니다. – nos
Boost.Asio는 libev에 대한 환상적인 대안이지만 이미 좋아하지는 않는다고 언급했습니다. 아마도 당신은 우려를 다른 질문으로 확장시킬 수 있습니까? –
@SamMiller 나는 그것을 여러 번 사용하려고 노력해 왔으며, 내가 필요로하는 것이 너무 복잡하고 복잡하다고 생각된다. 나는 물건을 간단하게 유지하고 싶다. –