【问题标题】:inet_pton() gives "Segmentation fault"inet_pton() 给出“分段错误”
【发布时间】:2014-02-14 03:52:00
【问题描述】:

在我的程序中,我使用inet_pton 函数,其中一种是两种方式:

第一个:如果参数中没有指定,则默认 IP。

inet_pton(AF_INET, defaultIP, &servaddr.sin_addr)

第二种:当给出命令行IP地址时。

inet_pton(AF_INET, argv[1], &servaddr.sin_addr)

问题是,第一个给我一个分段错误,而第二个没有。我觉得这与我如何传递默认 IP 有关,但我不太明白。我这样定义 defaultIP:

const char *defaultIP = "127.0.0.1";

我尝试了多种传入 IP 地址的方法,但均未成功。也许这甚至不是问题?但是,如果我在命令行中传入 127.0.0.1,则通过 argv 传入它可以正常工作。提前感谢您的任何回复!

根据要求,我正在使用的全部代码现在都在这里。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netdb.h>

#define SA struct sockaddr
#define MAXLINE     4096

void err_sys(const char*);

int
main(int argc, char **argv)
{   
    const char *defaultIP = "127.0.0.1";
    int                 sockfd, n;
    char                recvline[MAXLINE + 1];
    struct sockaddr_in  servaddr;
    char defaultAddr = 0;

    if (argc != 2)
        defaultAddr = 1;

    if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
        err_sys("socket error");

    memset(&servaddr, 0, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_port   = htons(13);    /* daytime server */

    if (defaultAddr = 1)
        if (inet_pton(AF_INET, defaultIP, &servaddr.sin_addr) <= 0)
            err_sys("inet_pton error for input IP address");
    else
        if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0)
            err_sys("inet_pton error for input IP address");

    if (connect(sockfd, (SA *) &servaddr, sizeof(servaddr)) < 0)
        err_sys("connect error");

    while ( (n = read(sockfd, recvline, MAXLINE)) > 0) {
        recvline[n] = 0;    /* null terminate */
        if (fputs(recvline, stdout) == EOF)
            err_sys("fputs error");
    }
    if (n < 0)
        err_sys("read error");

    exit(0);
}

void err_sys(const char* x) 
{ 
    perror(x); 
    exit(1); 
}

【问题讨论】:

  • 区别在于argv[1]是一个可修改的字符串而"127.0.0.1"不是,所以如果inet_pton()试图修改第二个参数,分段错误是合理的。不过,我不相信这是麻烦的根源。 …而且,在检查了inet_pton() 的定义后,我确信这不是问题所在:第二个参数是const char *
  • 您能否使用字符串文字发布一个简短的完整示例来演示失败?问题很可能与这种差异完全无关。
  • 好的,我已经添加了我的代码。来源自 Unix Network Programming 一书和我的编辑。

标签: c sockets networking


【解决方案1】:

这里有两个错误:

if (defaultAddr = 1)
    if (inet_pton(AF_INET, defaultIP, &servaddr.sin_addr) <= 0)
        err_sys("inet_pton error for input IP address");
else
    if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0)
        err_sys("inet_pton error for input IP address");

首先,你有=,你想要==。其次,您的else 的代码缩进不当,或者您忘记在必要的地方使用大括号:

if (defaultAddr == 1)
{
    if (inet_pton(AF_INET, defaultIP, &servaddr.sin_addr) <= 0)
        err_sys("inet_pton error for input IP address");
}
else
{
    if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0)
        err_sys("inet_pton error for input IP address");
}

我不必非常努力地发现错误:

$ gcc -O3 -g -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes \
>     -Wold-style-definition -Werror inet_pton.c -o inet_pton
inet_pton.c: In function ‘main’:
inet_pton.c:32:5: error: suggest parentheses around assignment used as truth value [-Werror=parentheses]
     if (defaultAddr = 1)
     ^
inet_pton.c:32:8: error: suggest explicit braces to avoid ambiguous ‘else’ [-Werror=parentheses]
     if (defaultAddr = 1)
        ^
inet_pton.c:42:5: error: implicit declaration of function ‘read’ [-Werror=implicit-function-declaration]
     while ( (n = read(sockfd, recvline, MAXLINE)) > 0) {
     ^
cc1: all warnings being treated as errors

来自 Mac OS X 10.9.1 Mavericks 上的 GCC 4.8.2。

更正后,我得到了输出(没有参数,所以使用默认 IP 地址):

connect error: Connection refused

这是合理的,我认为 — 我的机器上没有运行 daytime 服务器。

【讨论】:

  • 当然,这非常简单。我想我应该少花点时间在 Python 上!从字面上看,就在我的头上。感谢您的帮助,对不起,它是如此简单。 xD
  • 至少使用我展示的大多数选项来帮助自己。我们有时都会犯类似的错误,但请确保您的编译器为您提供最大的帮助。
猜你喜欢
  • 1970-01-01
  • 2019-02-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-10
相关资源
最近更新 更多