2014-11-24 86 views
2

我正在Linux中進行一些套接字編程,並且想知道當函數套接字(...)時如何獲取錯誤代碼;失敗。不過,我想要做的,採用socket(...)功能類似的事情在Linux中創建套接字時獲取錯誤代碼

//Resolve the server address and port 
    result = (struct addrinfo *) calloc(1, sizeof(struct addrinfo)); 
    iResult = getaddrinfo("google.com", DEFAULT_PORT, &hints, &result); 
    if (iResult != 0){ 
     printf("%d\n", iResult); 
     fprintf(stderr, "getaddrinfo failed: %s\n", gai_strerror(iResult)); 
     getchar(); 
     exit(EXIT_FAILURE); 
    } 

例如對於「的getaddrinfo」功能,我可以做到這一點。

根據此: http://linux.die.net/man/2/socket

該函數返回-1失敗,並設置errno爲相應的錯誤號。我如何訪問這個「errno」? 這是我到目前爲止的代碼:

int connectSocket = 0; 
connectSocket = socket(AF_INET, SOCK_STREAM, 0); 
printf("%d\n", connectSocket); 

if (connectSocket == -1){ 
    printf("socket failed with error: %s\n", error_string); //TODO: HELP DECLARING error_string 
    getchar(); 
    exit(EXIT_FAILURE); 
} 
+2

見'錯誤號(3 )'和'strerror(3)'手冊頁。 – 2014-11-24 02:28:52

+2

不要爲在'getaddrinfo()'的最後一個參數中傳遞的'addrinfo'分配內存。它會爲你分配'addrinfo',你傳遞給'freeaddrinfo()'釋放它:'result = NULL; iResult = getaddrinfo(...,&result); if(iResult == 0){...; freeaddrinfo(結果); }' – 2014-11-24 06:29:00

回答

7

errno是線程局部全局變量,在<errno.h>定義。許多庫函數的手冊頁將指示它們在出錯時返回-1,並設置errno

您可以使用strerror函數將errno值轉換爲有用的字符串。

在一般情況下,你應該像這樣的代碼:

#include <stdio.h> 
#include <errno.h> 

int main(void) { 
    int s; 

    s = socket(...); 
    if (s < 0) { 
     fprintf(stderr, "socket() failed: %s\n", strerror(errno)); 
     exit(1); 
    } 
} 

另外,glibc的的printf和朋友支持%m格式說明,它被替換strerror(errno)(不需要參數)。所以,上面的例子可以替換爲:

if (s < 0) { 
     fprintf(stderr, "socket() failed: %m\n"); 
     exit(1); 
    } 

而且使這一切更簡單,有perror功能,可打印出類似於上面的消息。

if (s < 0) { 
     perror("socket"); 
     exit(1); 
    } 

把所有東西包裝起來 - 錯誤處理不需要很複雜和冗長。把socket()調用,在一個聲明中測試< 0,上面的代碼看起來是這樣的,你會成爲一個真正的UNIX親:

#include <stdio.h> 
#include <errno.h> 

int main(void) { 
    int s; 

    if ((s = socket(...)) < 0) { 
     perror("socket"); 
     exit(1); 
    } 
} 
+0

奇怪的是:「fprintf(stderr,」socket()失敗:%s \ n「,strerror(errno));」似乎沒有工作!相反,它會退出程序。但其餘的都做到了!非常感謝! – 2014-11-24 02:38:11

+0

nit:'#define errno(* __ get_errno())'是合法的,它不一定是變量,它是一個宏,它擴展爲一個可修改的左值類型爲int和線程本地存儲器。 – mafso 2014-11-25 19:29:57

4

添加#include <errno.h>,你就可以讀取全局errno變量。

connectSocket = socket(AF_INET, SOCK_STREAM, 0); 
if (connectSocket < 0) { 
    if (errno == EACCESS) ... 

您可以使用perrorstdio.h基礎上errno值來打印錯誤信息,或者您可以使用strerrorstring.h訪問字符串描述錯誤代碼

connectSocket = socket(AF_INET, SOCK_STREAM, 0); 
if (connectSocket < 0) { 
    perror("socket"); 
    exit(EXIT_FAILURE); 
} 
相關問題