Socket response with problems on Android NDK

1

I'm trying to implement this library, parson , in C, but when I try to manipulate the data obtained via connection socket (SO link) , I get a null , which does not happen when I manually put json in C.

The problem is in the socket response, which is not received correctly, because in the android logcat everything before the answer is deleted, leaving a blank field.

Below is all the function used to get a response from the server.

#include "HttpGet.h"
#include <android/log.h>
#include <stdio.h> /* printf, sprintf */
#include <stdlib.h> /* exit, atoi, malloc, free */
#include <unistd.h> /* read, write, close */
#include <string.h> /* memcpy, memset */
#include <sys/socket.h> /* socket, connect */
#include <netdb.h> /* struct hostent, gethostbyname */
#include <netinet/in.h> /* struct sockaddr_in, struct sockaddr */
#include "parson.h" // JSON

int HttpGetPost(char *webserver,const char *url)
{
    __android_log_print(ANDROID_LOG_INFO, "-----from--jni-------", "Enter HttpGet function!");
          char* argva = "?tokenweb=meuapp";

      __android_log_print(ANDROID_LOG_INFO, "-----from--jni-------", "Enter argvs %s ",argva);



    int argc = 5;
      char* argv[7];
      argv[1] = "127.0.0.1";
      argv[2] = "80";
      argv[3] = "GET"; //POST //GET
      argv[4] = "/testmobile.php";
      argv[5] = "?tokenweb=meuapp";
      argv[6] = "";
      __android_log_print(ANDROID_LOG_INFO, "-----from--jni-------", "Enter argv2 %s ",argv[4]);

    int i;
    struct hostent *server;
    struct sockaddr_in serv_addr;
    int bytes, sent, received, total, message_size;
    char *message, response[4096];
    int portno = atoi(argv[2])>0?atoi(argv[2]):80;
    char *host = strlen(argv[1])>0?argv[1]:"localhost";
    char *path = strlen(argv[4])>0?argv[4]:"/";
    if (argc < 5) { puts("Parameters: <host> <port> <method> <path> [<data> [<headers>]]"); exit(0); }
    /* How big is the message? */
    message_size=0;
    if(!strcmp(argv[3],"GET"))
    {
                printf("Process 1\n");
        message_size+=strlen("%s %s%s%s HTTP/1.0\r\nHost: %s\r\n");        /* method         */
        message_size+=strlen(argv[3]);                         /* path           */
        message_size+=strlen(path);                         /* headers        */
        if(argc>5)
            message_size+=strlen(argv[5]);                     /* query string   */
        for(i=6;i<argc;i++)                                    /* headers        */
            message_size+=strlen(argv[i])+strlen("\r\n");
        message_size+=strlen("\r\n");                          /* blank line     */
    }
    else
    {
                printf("Process 2\n");
        message_size+=strlen("%s %s HTTP/1.0\r\nHost: %s\r\n");
        message_size+=strlen(argv[3]);                         /* method         */
        message_size+=strlen(path);                            /* path           */
        for(i=6;i<argc;i++)                                    /* headers        */
            message_size+=strlen(argv[i])+strlen("\r\n");
        if(argc>5)
            message_size+=strlen("Content-Length: %d\r\n")+10; /* content length */
        message_size+=strlen("\r\n");                          /* blank line     */
        if(argc>5)
            message_size+=strlen(argv[5]);                     /* body           */
    }
            printf("Allocating...\n");
    /* allocate space for the message */
    //message=malloc(message_size); //original
    message=malloc(1024);

    /* fill in the parameters */
    if(!strcmp(argv[3],"GET"))
    {
        if(argc>5)
            sprintf(message,"%s %s%s%s HTTP/1.0\r\nHost: %s\r\n",
                strlen(argv[3])>0?argv[3]:"GET",               /* method         */
                path,                                          /* path           */
                strlen(argv[5])>0?"?":"",                      /* ?              */
                strlen(argv[5])>0?argv[5]:"",host);            /* query string   */
        else
            sprintf(message,"%s %s HTTP/1.0\r\nHost: %s\r\n",
                strlen(argv[3])>0?argv[3]:"GET",               /* method         */
                path,host);                                    /* path           */
        for(i=6;i<argc;i++)                                    /* headers        */
            {strcat(message,argv[i]);strcat(message,"\r\n");}
        strcat(message,"\r\n");                                /* blank line     */
    }
    else
    {
        sprintf(message,"%s %s HTTP/1.0\r\nHost: %s\r\n",
            strlen(argv[3])>0?argv[3]:"POST",                  /* method         */
            path,host);                                        /* path           */
        for(i=6;i<argc;i++)                                    /* headers        */
            {strcat(message,argv[i]);strcat(message,"\r\n");}
        if(argc>5)
            sprintf(message+strlen(message),"Content-Length: %d\r\n",(int)strlen(argv[5]));
        strcat(message,"\r\n");                                /* blank line     */
        if(argc>5)
            strcat(message,argv[5]);                           /* body           */
    }
    printf("Processed\n");
    /* What are we going to send? */
    printf("Request:\n%s\n",message);
        /* lookup the ip address */

    total = strlen(message);
    /* create the socket */


    int sockfd;
    server = gethostbyname(host);
    if (server == NULL) {
        error("ERROR, no such host");
        __android_log_print(ANDROID_LOG_INFO, "-----from--jni-------", "ERROR, no such host");
    }
        sockfd = socket(AF_INET, SOCK_STREAM, 0);
        if (sockfd < 0) {
            error("ERROR opening socket");
            __android_log_print(ANDROID_LOG_INFO, "-----from--jni-------", "ERROR opening socket");
        }
        /* fill in the structure */
        memset(&serv_addr,0,sizeof(serv_addr));
        serv_addr.sin_family = AF_INET;
        serv_addr.sin_port = htons(portno);
        memcpy(&serv_addr.sin_addr.s_addr,server->h_addr,server->h_length);
                /* connect the socket */
        if (connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0) {
            error("ERROR connecting");
            __android_log_print(ANDROID_LOG_INFO, "-----from--jni-------", "ERROR connecting");
        }
                /* send the request */

    sent = 0;
    do {
        bytes = write(sockfd,message+sent,total-sent);
        if (bytes < 0)
            error("ERROR writing message to socket");
        if (bytes == 0)
            break;
        sent+=bytes;
    } while (sent < total);
    /* receive the response */
    memset(response, 0, sizeof(response));
    total = sizeof(response)-1;
    received = 0;
    printf("Response: \n");

    /*
    do {
       printf("%s", response);
       __android_log_print(ANDROID_LOG_INFO, "-----from--jni-------", "Response: \n %s", response);

       //strcat(json_response, response);
       //strcpy(json_response,  response);
       json_response = response;

       memset(response, 0, sizeof(response));
       bytes = recv(sockfd, response, 1024, 0);
        if (bytes < 0)
           printf("ERROR reading response from socket");
       if (bytes == 0)
           break;
       received+=bytes;
    } while (1);
    */
    do {
        bytes = read(sockfd,response+received,total-received);
        __android_log_print(ANDROID_LOG_INFO, "---from--jni-RN---", "Response: %s", response);
        if (bytes < 0)
            error("ERROR reading response from socket");
        if (bytes == 0)
            break;
        received+=bytes;
    } while (received < total);

    if (received == total)
        error("ERROR storing complete response from socket");

    //__android_log_print(ANDROID_LOG_INFO, "-----from--jni-------", "Response2: \n %s", response);


//============ Verificação de Segurança =================================================//
      __android_log_print(ANDROID_LOG_INFO, "-----from--jni-1-----", "Response: \"%s\"", response); // = {"message":"success"}"
      __android_log_print(ANDROID_LOG_INFO, "-----from--jni-1a-----", "Response: '%s'", response);

      JSON_Value *user_data = json_parse_string(response);

      const char *msgs = json_object_get_string(json_object(user_data), "message");

    //Auth HashCode
//  __android_log_print(ANDROID_LOG_INFO, "-----from--jni-------", "Response Compare: \n [%s]", name );
        __android_log_print(ANDROID_LOG_INFO, "-----from--jni-1-----", "Json Message  1. [%s] ", msgs);
        //__android_log_print(ANDROID_LOG_INFO, "-----from--jni-2-----", "Signature Auth 2. [%s] \n",signature);

    //Auth PackageName

    char text[100] = "{\"key\": \"valor\"}";
    JSON_Value *data = json_parse_string(text);
    const char *sdata = json_object_get_string(json_object(data), "key");
    __android_log_print(ANDROID_LOG_INFO, "-----from--jni-1-----", "Json Key  1. [%s] \n", sdata);

    /* close the socket */
    close(sockfd);

    free(message);
    return 0;
}

Running the above code I get the following message in logcat.

com.dou361.ijkplayer_simple.example I/-----from--jni-------: Enter mmain function!
com.dou361.ijkplayer_simple.example I/-----from--jni-------: Enter HttpGet function!
com.dou361.ijkplayer_simple.example I/-----from--jni-------: Enter argvs ?tokenweb=meuapp 
com.dou361.ijkplayer_simple.example I/-----from--jni-------: Enter argv2 /testmobile.php 
                                                             testando_msg
                                                             testando_msg
                                                             testando_msg"
                                                             testando_msg'
com.dou361.ijkplayer_simple.example I/-----from--jni-1-----: Json Message  1. [(null)] 
com.dou361.ijkplayer_simple.example I/-----from--jni-1-----: Json Key  1. [valor] 

Picture

How can I receive this answer correctly? Such as com.dou361.ijkplayer_simple.example I/-----from--jni-1-----: Json Message [testando_msg] .

    
asked by anonymous 20.08.2016 / 23:22

1 answer

0

The solution found, but not the most desired, is below, using do / while in a loop that occurs 2 times, it is possible to bypass null that is received while trying to get response . As response is being processed in the loop , 2 values are received, the first is null , and the second is the desired variable. Through if(msgs) you can ignore null and receive the data you want.

Follow the modified snippet.

do {
  char * httpbody = strstr(response, "{\"message\"");

  JSON_Value * user_data = json_parse_string(httpbody);
  const char * msgs = json_object_get_string(json_object(user_data), "message");

  if (msgs) {
    __android_log_print(ANDROID_LOG_INFO, "---from--jni----", "Response:[%s]", httpbody);
    __android_log_print(ANDROID_LOG_INFO, "---from--jni-json-", "Json Message [%s]", msgs);
  }
  bytes = recv(sockfd, response, 1024, 0);
  if (bytes < 0)
    printf("ERROR reading response from socket");
  if (bytes == 0)
    break;
  received += bytes;
} while (1);

With this, you can ignore the \r\n or blank line that is received with response .

Desired result:

com.dou361.ijkplayer_simple.example I/---from--jni----: Response:[{"message":"success"}]
com.dou361.ijkplayer_simple.example I/---from--jni-json-: Json Message [success]
    
31.08.2016 / 22:15