【问题标题】:Why is the program broken down when it runs at if((hptr = gethostbyname(buffer)) == NULL)为什么程序在 if((hptr = gethostbyname(buffer)) == NULL) 运行时会崩溃
【发布时间】:2015-06-23 13:00:11
【问题描述】:

这是一个套接字通信的服务器。当客户端向服务器发送 URL 时,服务器将 IP 发送给客户端。当它运行hptr = gethostbyname(buffer) 时,它总是返回NULL。为什么?谢谢!

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

int main( int argc, char *argv[] )
{
    int sockfd, streamfd, addr_size, status;
    char buffer[256];
    struct sockaddr_in serv_addr, cli_addr;
    struct in_addr **addr_list;

    struct hostent *hptr;
    char  *ptr, **pptr;
    char  str[32];
    sockfd = socket(PF_INET, SOCK_STREAM, 0);

    if (sockfd < 0)
    {   
       perror("ERROR opening socket");
       exit(1);
    }

   /* Initialize socket structure */
   bzero((char *) &serv_addr, sizeof(serv_addr));

   serv_addr.sin_family = PF_INET;
   serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
   serv_addr.sin_port = htons(1234);

  /* Now bind the host address using bind() call.*/
  if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
  {
  perror("ERROR on binding");
  exit(1);
  }

  /* Now start listening for the clients, here process will
   * go in sleep mode and will wait for the incoming connection
  */

  listen(sockfd,10);
  addr_size = sizeof(cli_addr);

  /* Accept actual connection from the client */
  while(1){
       streamfd = accept (sockfd, (struct sockaddr *) &cli_addr, &addr_size);   

       status = read (streamfd, buffer, 255);   
       printf ("string from net: %s\n", buffer);



       if((hptr = gethostbyname(buffer)) == NULL)
       {
           printf("gethostbyname error for host:%s\n", buffer);
           return 0; 
       }



       printf("IP Address:%s\n",inet_ntoa(*((struct in_addr *)hptr->h_addr)));
       close(streamfd); 
    }
    return 0;
}

【问题讨论】:

  • string from net: 说什么?
  • 客户端发送什么?它是否包含空终止符?它是否包含换行符(例如,如果客户端中的字符串是用fgets 输入的)?它是否包含任何前导/尾随空格? read 成功了吗? read 返回什么?
  • @donjuedo - 可能没有任何内容和/或垃圾,因为假设可以通过 TCP 传输超过一个字节的消息,读取 read() 返回的结果以及缺乏安全的空终止,(即. 所有常见的嫌疑犯)。
  • 我想知道gethostbyname()的参数是否错误?“缓冲区”是一个数组。
  • 是的,几乎可以肯定是错的。

标签: c unix-socket gethostbyname


【解决方案1】:

发布的代码甚至还没有接近编译。

1) bzero() needs (note the plural 'strings')
    #include <strings.h> for bzero()
2) accept() parameter 3 has incorrect signedness
3) accept() return parameter should be socklen_t* but is int*
4) on linux for read() needs 
    #include <unistd.h>
5) inet_ntoa() needs 
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
6) several unused variables and parameters.
7) variable 'status' set but not used

强烈建议编译时启用所有警告

(对于 gcc,至少是 '-Wall -Wextra -pedantic')

然后修复警告。

为了便于我们人类阅读,请始终缩进代码

许多系统函数返回一个值,可用于确定操作是否成功。 read() 就是这样一个函数。

代码需要对read()返回的值进行错误检查

【讨论】:

    【解决方案2】:

    出于某种原因,您假设:

    1. read 总是成功并返回一个完整的chunk,发件人在一次send 调用中发送。
    2. 读取的数据以零结尾。

    这两个假设都不正确。

    您需要确保您阅读了完整的消息或一行(无论您使用何种有线协议),并且您的字符串是零终止的(人们通常不会通过线路发送零终止符)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-09
      • 2022-12-29
      • 2017-04-01
      相关资源
      最近更新 更多