2014-11-24 90 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); 
} 
相关问题