2013-08-25 39 views
1

我正在嘗試在C++中編寫套接字抽象。我正在使用poll()系統調用來等待數據準備好讀取。然而,當我運行我的程序時,poll()永遠不會返回,如果我將它設置爲無限輪詢,即使我發送套接字數據。當數據準備好時poll(2)不返回

這是一個簡單的程序來說明我的問題。我正在用OSX在OSX上編譯它:clang++ -g -Wall -pedantic -std=c++0x -stdlib=libc++ pollTest.cpp -o pollTest。我正在使用nc程序爲程序建立一個監聽套接字來連接。當我運行這個時,poll()調用永遠掛起,由於數據準備好讀取而永遠不會返回。

#include <poll.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netinet/tcp.h> 
#include <netdb.h> 
#include <unistd.h> 
#include <poll.h> 
#include <fcntl.h> 
#include <cstdlib> 
#include <iostream> 

void connectSocket(int& fd, std::string hostname, std::string service) { 
    struct addrinfo hints, *res, *res0; 
    int error; 
    int s; 
    memset(&hints, 0, sizeof(hints)); 
    hints.ai_family = AF_INET; 
    hints.ai_socktype = SOCK_STREAM; 
    error = getaddrinfo(hostname.c_str(), service.c_str(), &hints, &res0); 
    if (error) { 
    throw error; 
    } 
    s = -1; 
    for (res = res0; res; res = res->ai_next) { 
    s = socket(res->ai_family, res->ai_socktype, 
       res->ai_protocol); 
    if (s < 0) { 
     continue; 
    } 

    if (connect(s, res->ai_addr, res->ai_addrlen) < 0) { 
     close(s); 
     s = -1; 
     continue; 
    } 

    break; /* okay we got one */ 
    } 

    if (s < 0) { 
    throw s; 
    } 
} 

int main() { 
    int socketFileDescriptor = -1; 
    connectSocket(socketFileDescriptor, "localhost", "9999"); 

    pollfd socketPolls[1]; 
    socketPolls[0].fd = socketFileDescriptor; 
    socketPolls[0].events = POLLIN | POLLPRI | POLLRDBAND | POLLRDNORM; 
    poll(socketPolls, 1, -1); 
    std::cerr << socketPolls[0].revents; 
} 

關於爲什麼會發生這種情況的任何想法?我感覺好像我已經很好地閱讀了文檔,並且正確地使用系統調用。 (我沒有在這個示例程序中進行錯誤檢查,但是我在我的項目中執行)。任何幫助,將不勝感激!

回答

4

connectSocket,你從來沒有設置fd任何位置,因此在mainsocketFileDescriptor仍然-1poll會找不到插座上的所有數據。你可能打算統一sfd。也就是說,我認爲你最好返回文件描述符而不是使用引用。

+0

對,愚蠢的錯誤。修復後,民意調查確實會返回......至少讓我的呼吸更加輕鬆,因爲知道這是我的代碼被破壞了,而不是別人的密碼。 但是不應該輪詢返回,但POLLNVAL標誌被設置?因爲我使用-1作爲描述符? –

+0

@Chris:令人驚訝的是,我的系統手冊頁沒有記錄這一點,但是[poll]的POSIX規範(http://pubs.opengroup.org/onlinepubs/9699919799/functions/poll.html)表示「如果'fd'的值小於0,'poll'將被忽略,並且'revents'應該在從'poll()'返回的條目中被設置爲0。 – icktoofay