2015-06-23 12 views
0

Это сервер сокетов. Когда клиент отправляет URL-адрес на сервер, сервер отправляет IP-адрес клиенту. Когда он запускает hptr = gethostbyname(buffer), он всегда возвращает NULL. Зачем? Спасибо!Почему программа разбивается, когда она работает на if ((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; 
} 
+2

Что такое 'string from net:' say? – donjuedo

+0

Что отправляет клиент? Включает ли он нулевой ограничитель? Он содержит новую строку (например, если строка на клиенте была введена с помощью 'fgets')? Имеет ли он какое-либо ведущее/конечное белое пространство? Превосходит ли 'read'? Что читает 'read'? –

+0

@donjuedo - возможно, ничего и/или мусор из-за того, что сообщения, содержащие более одного байта, могут быть переданы через TCP, что приводит к результату, возвращаемому read(), и к отсутствию защищенного нулевого завершения (т. Е. Всех обычных подозреваемых). –

ответ

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 

Настоятельно рекомендуем при компиляции, чтобы все предупреждения

(для НКУ, как минимум, '-Wall -Wextra -pedantic')

Затем исправить предупреждения.

пожалуйста последовательно выравнивал код, для удобочитаемости нас людям

многих системных функций возвращают значение, которое может быть использовано для определения, если операция прошла успешно. read() - такая функция.

Код должен выполнить проверку ошибок по возвращаемому значению из read()

1

По какой-то причине вы предполагаете, что:

  1. read всегда преуспевает и возвращает вам полный кусок что отправитель послал в одном send вызова.
  2. Данные считаются нулевыми.

Оба эти предположения неверны.

Вам необходимо убедиться, что вы прочитали полное сообщение или строку (независимо от вашего проводного протокола) и что ваши строки имеют нулевое завершение (люди часто не отправляют нулевые терминаторы по проводу).

+0

Большое спасибо. – DaveyTao