2016-08-21 74 views
2

我對套接字編程相當陌生,我試圖編寫一個程序來獲得傳入的TCP連接並以某種方式管理它們。我想不通,爲什麼下面的代碼是給我一個「人頭錯誤」:什麼導致poll()函數,C++錯誤?

int main(int argc, char *argv[]) { 
char *port; 
struct pollfd connections[MAX_CONNECTIONS]; 
struct addrinfo addr_hints, *addr_result; 
int ret, i; 

for (i = 0; i < MAX_CONNECTIONS; ++i) { 
    connections[i].fd = -1; 
    connections[i].events = POLLIN; 
    connections[i].revents = 0; 
} 

port = "0"; 

memset(&addr_hints, 0, sizeof(struct addrinfo)); 
addr_hints.ai_flags = AI_PASSIVE; 
addr_hints.ai_family = AF_UNSPEC; 
addr_hints.ai_socktype = SOCK_STREAM; 
addr_hints.ai_protocol = IPPROTO_TCP; 

getaddrinfo(NULL, port, &addr_hints, &addr_result); 

connections[0].fd = socket(addr_result->ai_family, addr_result->ai_socktype, addr_result->ai_protocol); 

if (connections[0].fd < 0) { 
    cerr << "Socket error" << endl; 
    return 0; 
} 

if (bind(connections[0].fd, addr_result->ai_addr, addr_result->ai_addrlen) < 0) { 
    cerr << "Bind errror" << endl; 
    return 0; 
} 

if (listen(connections[0].fd, 25) < 0) { 
     cerr << "Listen error" << endl; 
    return 0; 
} 

do { 
    for (i = 0; i < MAX_CONNECTIONS; ++i) 
      connections[i].revents = 0; 

    ret = poll(connections, MAX_CONNECTIONS, -1); 

    if (ret < 0) { 
     cerr << "Poll error" << endl; 
     return 0; 
    } else { 
     //DO SOMETHING 
    } 

} while(true); 
} 

MAX_CONNECTIONS是一個常數設置爲10000連接[0]應該是關於這一點我正在聽的描述符傳入連接。我將端口設置爲「0」,因爲我想選擇一個隨機端口。似乎輪詢函數立即失敗,產生消息「輪詢錯誤」(所以poll()基本上小於0)。我已經檢查並在輪詢和綁定連接[0]後有一個文件描述符。我不知道我在做什麼錯,是getaddrinfo函數的東西嗎?

+4

當你從系統收到一個錯誤叫你需要檢查['errno'](http://man7.org /linux/man-pages/man3/errno.3.html)來獲取錯誤代碼。您可以使用例如['strerror'](http://en.cppreference.com/w/cpp/string/byte/strerror)獲取可打印的錯誤字符串。 –

+0

我明白了。我按你的建議做了,結果證明這是一個「無效參數」錯誤。對於pollfd結構的大小是否有某種限制?我不知道這裏還有什麼可能是錯的。 – TheMountainThatCodes

回答

3

問題是您的輪詢文件描述符數組太大。它的最大尺寸可以定義爲RLIMIT_NOFILE。對於您的系統,這可能是1024。將MAXIMUM_CONNECTIONS降至此值或更低。

從調查規格:

EINVAL The nfds value exceeds the RLIMIT_NOFILE value. 

多見於:http://man7.org/linux/man-pages/man2/poll.2.html

相關問題