2016-03-03 35 views
0

我有一個相對簡單的服務器,它應該打開服務器套接字並接受一個客戶端套接字連接。Linux插座接受總是失敗

if(!(STARTUP)) 
{ 
// CAN Socket öffnen 
can_soc = initialize_CAN(); 

// TCP Socket öffnen 
tcp_soc = initialize_TCP(strtol(argv[1],NULL,10)); 

STARTUP = 1; 
} 


// Jede empfangene CAN Botschaft auf TCP umleiten 
while(!(EXIT_FLAG)) 
{ 

if(!(CLIENT_CONNECTED)) // Wenn keiner verbunden ist, wird gelistened 
{ 
    // LISTEN // 
     listen(tcp_soc,2); 

    std::cout << "Waiting for incoming TCP connection...\n"; 

    c = sizeof(struct sockaddr_in); 

    tcp_client_soc = accept(tcp_soc, (struct sockaddr *)&client, (socklen_t*)&c); 

    if(tcp_client_soc < 0) 
    { 
    std::cout << "ERROR: accept failed\n"; 
    EXIT_FLAG = 1; 
    return 0; 
    } 
    else 
    { 
    std::cout << "Connection from " << inet_ntoa(client.sin_addr) << " accepted!\n"; 
    // --> NEUER CLIENT AKZEPTIERT // 
    CLIENT_CONNECTED = 1; 
    } 
} 
else   // ansonsten: CAN auf TCP leiten 
{ 
    std::cout << "nop" << std::endl; 
} 

} 

現在的問題是,該程序總是終止在「ERROR:接受失敗」,這意味着接受總是提供-1與正在建立的無連接(O_NONBLOCK沒有被設置)。

int initialize_TCP(int pPort) 
{ 
    int tcp_soc; 

    std::cout << "Creating TCP socket and binding to PORT: " << pPort << "... "; 

    tcp_soc = socket(AF_INET, SOCK_STREAM, 0); 

    if(tcp_soc == -1) 
    { 
     std::cout << "ERROR: Could not create socket!\n"; 

    EXIT_FLAG = 1; 
    } 


    server.sin_addr.s_addr = INADDR_ANY; //do not specify IP (got a server here) 
    server.sin_family = AF_INET; 
    server.sin_port = htons(pPort); 

    // BIND // 

    if(bind(tcp_soc,(struct sockaddr *)&server, sizeof(server)) < 0) 
    { 
     std::cout << "Binding failed! Restarting network service ...\n"; 

     system("/etc/init.d/networking restart"); //Restarted Network Servcie wenn Binding nicht geht 

     std::cout << "Binding again... "; 
     bind(tcp_soc,(struct sockaddr *)&server, sizeof(server)); 
     std::cout << "OK\n"; 
    } 


    std::cout << "OK\n"; 
} 

那麼問題在哪裏?也許每次都有未知的連接?或者它是一個語法問題?

+1

你在'while'循環中調用'listen()'。它應該在循環之外,或者在'bind()'成功之後的'initialize_TCP()'中更好。無論哪種方式,當accept()(或任何其他套接字函數)失敗時,errno的值是什麼?你應該輸出到'cout'。另外,你也應該輸出'strerror()'的結果。另外,請不要重新啓動網絡服務,這不是您的應用程序的責任。讓用戶去做。但是如果你重新啓動,你可能不得不從頭開始重新創建你的監聽套接字。你沒有檢查重試的bind()失敗。 –

+0

您還需要應用相同的錯誤檢查,以'插座(),聽(),bind()的,...' – EJP

+0

感謝@RemyLebeau,我實現了錯誤號,它表明88,「關於非插座式操作」,這意味着套接字沒有正確初始化我假設? – rele92

回答

0

發現問題,插座並不在場所以ERRNO遞送代碼88. ,其通過未正確返回的套接字描述符引起的。