【问题标题】:segmentation fault - socket programming分段错误 - 套接字编程
【发布时间】:2012-09-28 02:54:57
【问题描述】:

我在运行一小段代码时遇到问题。这是关于 C 中的套接字编程。我想做的是让客户端在两个不同的端口上与服务器通信。但是当我试图编译客户端代码时,我得到了“分段错误”。我在这里给我的客户代码。请让我知道出了什么问题。

    #include<stdio.h>
    #include<stdbool.h>
    #include<string.h>
    #include<stdlib.h>
    #include<time.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <netdb.h>

    int main(int argc,char *argv[])
    {
     int sockfd,newsockfd,sockfd_infinite,sockfd_kitchen,portno,portno1,n,no_of_tables;
     struct sockaddr_in serv_addr,kitchen_addr;
     struct hostent *server,*kitchen;
     struct timeval time_out;
     time_out.tv_sec = 15;    // 15 seconds
     time_out.tv_usec = 0;    // 0 milliseconds
    //       server=gethostbyname(argv[1]);
    //       char buffer[256];
     portno=atoi(argv[2]);
     portno1=atoi(argv[4]);
     sockfd=socket(AF_INET,SOCK_STREAM,0);
     if(sockfd==-1)
            error("\nError creating socket");
     server=gethostbyname(argv[1]);
     serv_addr.sin_family=AF_INET;
     serv_addr.sin_port=htons(portno);
     bcopy((char *)server->h_addr,
            (char *)&serv_addr.sin_addr.s_addr,
            server->h_length);

     sockfd_kitchen=socket(AF_INET,SOCK_STREAM,0);
     if(sockfd_kitchen==-1)
            error("\nError creating socket");
     kitchen=gethostbyname(argv[3]);
     kitchen_addr.sin_family=AF_INET;
     kitchen_addr.sin_port=htons(portno1);
     bcopy((char *)kitchen->h_addr,
            (char *)&kitchen_addr.sin_addr.s_addr,
            kitchen->h_length);

     n=connect(sockfd_kitchen,(struct sockaddr *)&kitchen_addr,sizeof(kitchen_addr));
     if(n==-1)
            error("\nError connecting to kitchen");
     n=connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr));
     if(n==-1)
            error("\nError connecting to server");
     return 0;
    }

所以这段代码背后的想法是——有一个客户端和一个服务器。该客户端希望在两个不同的端口上与服务器通信,就好像客户端正在与两个不同的服务器通信一样。我在我的笔记本电脑上执行此操作,将服务器名称作为服务器名称和不同端口号的“localhost”提供。就像您在我的代码中看到的那样,我有两个用于两个服务器的指针变量,即 *server 和 *kitchen。

例如: ./thiscode 本地主机 15535 本地主机 12345

在我提到的示例中,这就是我编译客户端代码的方式。 argv[1] 是第一个“localhost”(服务器名称),argv[2] 是第一个服务器的端口号。第二个“localhost”和“12345”是第二个服务器的名称和端口号。

就像我之前说过的,我试图让我的笔记本电脑上的三个窗口运行三种不同的代码(一个用于客户端,两个用于服务器)。我的两个服务器代码编译没有任何问题,但我的客户端代码出现了这个“分段”错误。请让我知道我哪里出错了。 谢谢。

【问题讨论】:

  • 您的编译器中没有错误,您在编译时没有获得 SEGV。当你跑步时,你会得到它。在那里,我已经达到了当天的迂腐配额:-)
  • 当您的程序崩溃、分段错误或任何其他问题时,您作为程序员的第一反应应该是在调试器中运行您的程序。它将帮助您定位崩溃的位置,并让您检查变量以帮助您找出崩溃的原因。
  • 一些 cmets: (1) 您的代码在使用 argv 之前不会检查 argc,因此如果您在没有参数的情况下运行程序,那么您将在那里溢出。 (2) 即使给出了正确数量的参数,您也应该检查它们是否被正确解析。 (3) valgrind 在运行这段代码时会产生大量的输出,所以你应该听从 Joachim 的建议。
  • 您的调试器对此有何看法?

标签: c sockets


【解决方案1】:

首先,您应该检查来自gethostbyname 的返回值:

如果发生错误,gethostbyname() 和 gethostbyaddr() 函数会返回 hostent 结构或 NULL 指针。出错时,h_errno 变量保存一个错误号。

【讨论】:

  • 我确实用 HOST_NOT_FOUND 值检查了 h_errno。对于 C 中的普通服务器-客户端套接字编程,即使 h_errno 等于 HOST_NOT_FOUND,我仍然可以在服务器和客户端之间传输数据。我不清楚这是怎么回事!
  • @Richard, h_errno(就像errno)是无关紧要的除非返回值指示错误。否则,它可以设置为any 值。换句话说,检查函数是否返回 NULL,如果返回,则查看h_errno。
【解决方案2】:

看来问题出在bcopy()函数调用上。

在将内容复制到变量之前,您没有为变量声明空间,因此您看到了分段错误。

在bcopy() 语句前输入以下代码以消除Seg-fault:

serv_addr.sin_addr.s_addr=malloc(sizeof(unsigned long));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多