2009-12-10 47 views
4

的Linux GCC 4.4.2插座迴歸「沒有這樣的文件或目錄」

我做一些socket編程。

然而,當我嘗試和分配從插座功能的sockfd我不斷收到此錯誤。

" Socket operation on non-socket" 

任何意見非常感謝,

#if defined(linux) 
#include <pthread.h> 
/* Socket specific functions and constants */ 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <netdb.h> 
#include <errno.h> 
#endif 

#include "server.h" 
#include "cltsvr_ults.h" 

/* Listens for a connection on the designated port */ 
void wait_client() 
{ 
    struct addrinfo add_info, *add_res; 
    int sockfd; 

    /* Load up the address information using getaddrinfo to fill the struct addrinfo */ 
    memset(&add_info, 0, sizeof(add_info)); 
    /* Use either IPv4 or IPv6 */ 
    add_info.ai_family = AF_UNSPEC; 
    add_info.ai_socktype = SOCK_STREAM; 
    /* Fill in my IP address */ 
    add_info.ai_flags = AI_PASSIVE; 

    /* Fill the struct addrinfo */ 
    int32_t status = 0; 
    if(status = getaddrinfo(NULL, "6000", &add_info, &add_res) != 0) 
    { 
     fprintf(stderr, "getaddrinfo [ %s ]\n", gai_strerror(status)); 

     return; 
    } 

    if((sockfd = (socket(add_res->ai_family, add_res->ai_socktype, add_res->ai_protocol)) == -1)) 
    { 
     fprintf(stderr, "Socket failed [ %s ]\n", strerror(errno)); 

     return; 
    } 

    /* Bind to the port that has been assigned by getaddrinfo() */ 
    if(bind(sockfd, add_res->ai_addr, add_res->ai_addrlen) != 0) 
    { 
     fprintf(stderr, "Bind failed [ %s ]\n", strerror(errno)); 

     return; 
    } 

    printf("Listening for clients\n"); 
} 

編輯==編碼老 - 學校的方法

int32_t sockfd = 0; 
    struct sockaddr_in my_addr; 

    memset(&my_addr, 0, sizeof(my_addr)); 

    my_addr.sin_family = AF_INET; 
    my_addr.sin_port = htons(6000); 
    my_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); 

    sockfd = socket(PF_INET, SOCK_STREAM, 0); 
    if(sockfd == -1) 
    { 
    fprintf(stderr, "Socket failed [ %s ]\n", strerror(errno)); 
    return; 
    } 

    if(bind(sockfd, (struct sockaddr *) &my_addr, sizeof(my_addr)) == -1) 
    { 
    fprintf(stderr, "Bind failed [ %s ]\n", strerror(errno)); 
    return; 
    } 
+0

@robUK是有什麼特別的理由,爲什麼你正在使用'getaddrinfo'而不是做一個普通的'套接字(AF_INET,SOCK_STREAM,6000) ;'? – RageZ 2009-12-10 07:35:43

+0

嗯,我使用的是getaddrinfo,因爲這是最新的方式來做到這一點,另一種方式已經過時。我使用Beej的參考。謝謝。 – ant2009 2009-12-10 07:43:03

+0

RageZ:'6000'對於套接字的第三個參數不是一個合適的值。 – caf 2009-12-10 10:20:48

回答

12

您的主要問題是,你有錯誤的檢查當socket()有錯誤。 socket()將在錯誤時返回-1,而不是在成功時返回0。你可能會得到一個很好的套接字值(2,3等)並將其視爲一個錯誤。

還有第二個問題是你加入代碼的方式。當你寫:

if (sockfd = socket(add_res->ai_family, add_res->ai_socktype, add_res->ai_protocol) != 0) 

正被視爲:

if (sockfd = (socket(add_res->ai_family, add_res->ai_socktype, add_res->ai_protocol) != 0)) 

那麼的sockfd將不會分配插座的返回值,但它比較反對0修復這兩個問題的價值,你應該寫:

if ((sockfd = socket(add_res->ai_family, add_res->ai_socktype, add_res->ai_protocol)) == -1) 
+0

謝謝。這是正確的。但是,我現在收到錯誤「在非套接字上的套接字操作」。我使用正確的行編輯了我的代碼。任何理由爲什麼我得到這個錯誤?非常感謝 – ant2009 2009-12-10 12:32:26

+0

@roboUK - 您確定您從發佈爲「編輯」的代碼中獲得了該錯誤。當我編譯該代碼段並運行它時,它運行良好。 – 2009-12-10 19:15:01

0

我相信你應該指定你想要的插座類型。當你說:

add_info.ai_family = AF_UNSPEC; 

,你應該說:

add_info.ai_family = AF_INET; 
+0

我將那行代碼更改爲AF_INET,但仍然收到相同的錯誤。 – ant2009 2009-12-10 13:28:08

+0

我不相信你對getaddrinfo()的調用是正確的。你爲什麼不簡單地遵循許多「老派」中關於如何使用套接字的例子。 – 2009-12-10 13:37:01

+0

你好,我編輯了我的源代碼,包括老派的方法。這工作正常。但是,我仍然有興趣知道爲什麼使用getaddrinfo()失敗?非常感謝, – ant2009 2009-12-10 16:44:21

相關問題