2016-02-16 5 views
-2

мне интересно, как преобразовать обугленного [] массив в полукокса *Как преобразовать char [] в char *?

Например, в моем коде я пытаюсь получить доступ к веб-серверу, используя имя хоста, как «example.com»

Использование мой код, если я установил char * на example.com, как показано ниже, он отлично работает.

char *host = "example.com"; 

Но то, что я действительно хочу сделать, это быть в состоянии прочитать из клиентской программы, используя сокет, запись в полукоксе [] массив, и использовать данные, полученные с, что в качестве имени хоста.

Например,

char buffer[4096], hostname[4096]; 

bzero(buffer, 4096); 
n = read(newsockfd, buffer, 4095); 

strcpy(hostname, buffer); 
printf("Here is the hostname: %s\n", &hostname[0]); 

int sockwb, wbport, x; 
struct sockaddr_in webser_addr; 
struct hostent *wbhost; 
char webbuf[4096];//sending to webserver 

wbport = 80;//port used to access web server 

sockwb = socket(AF_INET, SOCK_STREAM, 0); 

wbhost = gethostbyname(hostname); 

, когда мой код получает до последней строки, он просто сидит там, так что я имею в виду свою проблему типизации, так как, когда я делаю это:

char *host = "example.com"; 

... 

wbhost = gethostbyname(host); 

Он работает и может получать данные из Интернета и отправлять их должным образом в мою клиентскую программу.

Любые идеи приветствуются.

В клиентской программе я использую fgets() для чтения в char [] из stdin, а затем write() для записи в сокет для программы сервера. Я попытался использовать strcat(), чтобы добавить '\ 0' в конец символа [], прежде чем писать в сокет, но ничего не сделал

Полный код: (Пожалуйста, проигнорируйте комментарии, просто пробовать разные вещи, в настоящее время) клиента

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


int main(int argc, char *argv[]) 
{ 

    int sockfd, portnum, n; 
    struct sockaddr_in serv_addr; 
    struct hostent *server; 

    char buffer[4096]; 

    if(argc < 3) 
    { 
    fprintf(stderr, "usage %s hostname port\n", argv[0]); 
    exit(1); 
    } 

    portnum = atoi(argv[2]); 
    sockfd = socket(AF_INET, SOCK_STREAM, 0); 

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

    server = gethostbyname(argv[1]); 

    if(sockfd == NULL) 
    { 
    fprintf(stderr, "ERROR, no such host\n"); 
    exit(1); 
    } 

    bzero((char *) &serv_addr, sizeof(serv_addr)); 

    serv_addr.sin_family = AF_INET; 
    bcopy((char *)server->h_addr, (char *)&serv_addr.sin_addr.s_addr, server->h_length); 

    serv_addr.sin_port = htons(portnum); 

    if(connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) 
    { 
    fprintf(stderr, "ERROR, on connecting"); 
    exit(1); 
    } 

    printf("Please enter the Host name: "); 
    bzero(buffer, 4096); 
    fgets(buffer, 4095, stdin); 
    //strcat(buffer, "\0"); 

    n = write(sockfd, buffer, strlen(buffer)); 

    if(n < 0) 
    { 
    printf("Error writing to socket"); 
    exit(1); 
    } 

    bzero(buffer, 4096); 
    n = read(sockfd,buffer, 4095); 

    if(n < 0) 
    { 
    printf("ERROR reading from socket"); 
    exit(1); 
    } 
    printf("%s\n", buffer); 

    return 0; 
} 

сервер

#include <stdio.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <arpa/inet.h> 
#include <unistd.h> 
#include <sys/wait.h> 
#include <stdlib.h> 
#include <netdb.h> 
#include <string.h> 



int main(int argc, char *argv[]) 
{ 

    int sockfd, newsockfd, portnum, clilen; 
    char buffer[4096], hostname[4096]; 
    pid_t p_id; 
    struct sockaddr_in serv_addr, cli_addr; 
    int n, pid, hostname_len; 
    //char *host; 
    char *host = "example.com"; 

    if(argc < 2) 
    { 
     fprintf(stderr, "ERROR, NO PORT PROVIDED!\n"); 
     exit(1); 
    } 

    sockfd = socket(AF_INET, SOCK_STREAM, 0);//socket is made 

    if(sockfd < 0) 
    { 
     fprintf(stderr, "ERROR opening socket!!"); 
     exit(1); 
    } 

    bzero((char *) &serv_addr, sizeof(serv_addr)); 
    portnum = atoi(argv[1]);//port num 

    serv_addr.sin_family = AF_INET; 
    serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); 
    serv_addr.sin_port = htons(portnum); 


    if(bind(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) 
    { 
     fprintf(stderr, "ERROR on binding"); 
     exit(1); 
    } 

    if(listen(sockfd, 5) < 0) 
    { 
     printf("ERROR ON LISTEN"); 
     exit(1); 
    } 

    // accept 
    clilen = sizeof(cli_addr); 

    do{ 

     newsockfd = accept(sockfd, (struct sockaddr *)&cli_addr, &clilen); 
     if(newsockfd < 0) 
     { 
      fprintf(stderr, "ERROR on accept\n"); 
      exit(1); 
     } 

     pid = fork(); 
     if(pid == 0) 
     { 
      bzero(buffer, 4096); 
      n = read(newsockfd, buffer, 4095); 

      if(n < 0) 
      {//message from client 
       fprintf(stderr, "ERROR Reading from socket\n"); 
       exit(1); 
      } 

      strcpy(hostname, buffer); 
      printf("Here is the hostname: %s\n", &hostname[0]); 

      //variables used for acsessing webserver? 
      int sockwb, wbport, x; 
      struct sockaddr_in webser_addr; 
      struct hostent *wbhost; 
      char webbuf[4096];//sending to webserver 

      wbport = 80;//port used to access web server 

      sockwb = socket(AF_INET, SOCK_STREAM, 0); 

      if(sockwb < 0) 
      { 
       printf("Error opeing websocket\n"); 
       exit(1); 
      } 


     // hostname_len = sizeof(hostname)/sizeof(hostname[0]); 
     // printf("%d\n", hostname_len); 
     // memcpy(host, hostname, hostname_len); 
     // host[hostname_len] = '\0'; 
      printf("%s\n", host); 
     // hostname[hostname_len] = '\0'; 

     // host = &hostname[0]; 

      //wbhost = gethostbyname(hostname); 
      wbhost = gethostbyname(host); 
      //printf("%s", wbhost->h_name); 

      printf("here2\n"); 

      /*if(wbhost == NULL) 
      { 
       printf("NO SUCH web HOST\n"); 
       exit(1); 
      } 
      */ 
      bzero((char*) &webser_addr, sizeof(webser_addr)); 

      webser_addr.sin_family = AF_INET; 

      bcopy((char *)wbhost->h_addr, (char *)&webser_addr.sin_addr.s_addr, wbhost->h_length); 

      webser_addr.sin_port = htons(wbport); 

     // printf("here3\n"); 

      if(connect(sockwb, (struct sockaddr *) &webser_addr,sizeof(webser_addr)) < 0) 
      { 
       printf("Error on web connecting\n"); 
       exit(1); 
      } 

      bzero(webbuf, 4096); 
      strcpy(webbuf, "GET/HTTP/1.0\r\nHost: "); 
     // strcat(webbuf, hostname); 
      strcat(webbuf, host); 
      strcat(webbuf, "\r\nConnection: close\r\n\r\n"); 


     // const char * request = "GET/HTTP/1.0\r\nHost: example.com\r\nConnection: close\r\n\r\n"; 

     // printf("%s\n", request); 
     // x = write(sockwb, request, strlen(request)); 

      printf("%s\n", webbuf); 
      x = write(sockwb, webbuf, strlen(webbuf)); 

      if(x < 0) 
      { 
       printf("Error writing to web sock"); 
       exit(1); 
      } 

      bzero(webbuf, 4096); 
      x = read(sockwb, webbuf, 4096); 

      if(n < 0) 
      { 
       printf("Error reading from web socket"); 
       exit(1); 
      } 

      printf("%d\n", (int)strlen(webbuf)); 
      printf("%s\n",webbuf); 

      n = write(newsockfd, webbuf, 4095);//write back to client 

      if(n < 0) 
      { 
       fprintf(stderr, "ERROR WRITING to socket"); 
       exit(1); 
      } 

      //printf("%s\n", webbuf); 
     }//end of if pid==0 

     printf("closing client"); 
     close(newsockfd);//closing client socket 


    }while(1); 

    return 0; 
} 
+0

Включите в свой текст конечный нулевой байт? Во всяком случае, существует неявное преобразование из 'char [N]' в 'char *', поэтому это не должно быть проблемой. – Downvoter

+0

@cad Я так не думаю? В клиентской программе я использую fgets() для чтения в char [] из stdin, а затем write() для записи в сокет для чтения серверной программы. Я попытался использовать strcat(), чтобы добавить '\ 0' в конец символа [] перед записью в сокет, но это, похоже, ничего не делало. – Blake

+0

Отредактируйте это ** на свой вопрос **, а не как комментарий. – Downvoter

ответ

2

Код, который вы опубликовали, работает беспрепятственно. Когда вы обратитесь за помощью, вы всегда должны указывать пример complete, verifiable. Убедитесь, что код, который вы публикуете, действительно воспроизводит проблему!

Посмотрев, что делает код, кажется, что на сервере вы хотели использовать имя хоста, которое вы читаете как аргумент gethostbyname. Вы можете сделать это с

host = &hostname[0]; 

или проще

host = hostname; 

или не использованием двух отдельных переменных в первую очередь.

Когда вы используете массив в контексте, ожидающем значения (в отличие от, например, взяв его адрес или его sizeof), массив распадается на указатель на его первый элемент. Итак, здесь hostname эквивалентен hostname[0].

После этого изменения, проверьте след близко, или, чтобы сделать эту проблему более заметным, изменить линию трассировки для

  printf("[%s]\n", hostname); 

Вы увидите

[aaa.com 
] 

Клиент считывает строку с fgets, который включает в себя завершающий символ новой строки в своем счете. Клиент покорно передает всю строку на сервер. И поэтому сервер ищет имя хоста, содержащее символ новой строки, которого нет. Вы не проверяете код возврата gethostbyname (вы должны!), Он возвращает нулевой указатель, и программа вылетает, когда пытается ее прочитать.

+0

Хорошо, спасибо, что помогли мне увидеть, что там есть символ новой линии, я не стал его проверять. Какой был бы лучший способ его удалить? так что это будет '[example.com]' – Blake

+0

@Blake Обычно: найдите конец строки (с помощью 'strchr (buffer, 0)' с 'strlen'), проверьте, является ли это первым байтом (пустой ввод) и если он не проверяет байт перед нулевым байтом, и если это новая строка, замените его нулевым байтом. – Gilles

+0

Спасибо, это очень помогло с помощью @ Koffee! – Blake

0

Вероятно, самый простой способ 'новообращенного' char[] к char * является:

char example_array[] = "example"; 
char * example_pointer = (char *)calloc(1, strlen(example_array) + 1); // + 1 for the '\0' character 
strcpy(example_pointer, example_array); 
0

A char[] представляет собой массив символов. A char* - это указатель на char - обычно (но не всегда) начало строки.

Если вы хотите получить указатель на начало вашего массива, вам даже не нужно ничего делать! Это преобразование происходит неявно:

char hello[6] = {'h', 'e', 'l', 'l', 'o', '\0'}; 
// or: char hello[] = "hello"; (equivalent to above) 
printf("%s", hello); // prints hello 
puts(hello); // also prints hello 

char *hello2 = hello; 
puts(hello2); // also prints hello 
1

@Gilles правильно, у вас есть «\ п» в конце имени хоста, следующий фрагмент кода заменяет «\ п» на 0, что является эквивалентом символа «\ 0»:

extern int h_errno; 
    ... 
    hostname[strlen(hostname) - 1] = 0; 
    wbhost = gethostbyname(hostname); 

    if (!wbhost) { 
     printf("Failed! %s\n", strerror(h_errno)); 
     exit(1); 
    } 
    ... 
+0

Спасибо, это очень помогло! – Blake

Смежные вопросы