AnsweredAssumed Answered

TCP / IP Socket Client Issue (RTCS bug?)

Question asked by rick101 on Jul 5, 2013

TCP / IP Socket Client Issue (RTCS bug?)

 

I’m currently using MQX 3.8.1 and Code Warrior 10.3. I’ve written a TCP client to read a web page.

 

The client is based on the syntax from Freescale’s twitter example. I believe it s correct?, the code works okay when complied on a PC, so it seem like a bug in RTCS?.

 

Can some please test the following or any other help would be very useful

 

The Issue

The client connects to targets server but fails to receive a web page from another web server apart from MQX’s own (same board or difference board to the client).

 

Setup

I’ve based my test setup on MQX’s freescale web server example (\rtcs\examples\httpsrv). I’ve modified only one file (httpdsrv.c). The modification creates a test http client task after the web server is up and running, this then grabs one web page.  It’s very simple, I’ve attached the code, you can copy this file into Freescale’s demo and it should just compile and run.

 

 

Working setup terminal out looks like i.e. grabbing an image from its own web server

preparing http server...

run http server...

Http Task Running

Socket Created 35440

Socket Bind Completed 0

Connected to 172.18.11.11, port 80.

Command send to server:-

GET /rtc.html HTTP/1.0

Host: 172.18.11.11

 

"Response from server - comment added by me"

HTTP/1.0 200 OK

Server: MQX HTTP - Freescale Embedded Web Server

Connection: close

Content-Type: text/html

 

"Web Page being received - comment added by me"

<!DOCTYPE HTML SYSTEM>

<html>

<head>

 

Etc

 

Non working terminal output looks like i.e. connect to a non MQX web server

 

Connected to 172.18.11.53, port 80.

Command send to server:- GET /fs/about.htm HTTP/1.0

Host: 172.18.11.53

 

HTTP/1.1

Packet received of 9 Bytes Total Bytes Received 9

 

I do not get a complete HTTP response i.e. 200 / OK,  Server:  etc and no web page, it just hangs at this point

 

Main body of code is as follows (very much like the twitter example with some minor corrections): -

 

int_32 httpClient()

{

    uint_32 sockfd = 0;

    uint_32 sent = 0;

    uint_32 numBytes = 0;

    uint_32 loop=0;

    int_32  tmpres;

    uint_32 errCode;

    uint_32 result;

    uint_32 status;

    uint_32 opt_val1 = 10000;

    uint_32 opt_len1 = sizeof(int_32);

 

    struct sockaddr_in  client;

 

    /* create socket */

    sockfd = socket(AF_INET, SOCK_STREAM, 0 );

    if ( sockfd == RTCS_SOCKET_ERROR )

    {

        printf("httpClient() - error creating socket %d\n",sockfd);

        return ERROR;

    }

    printf("Socket Created %d\n",sockfd);

 

    /* added socket options - time out after */

    status = setsockopt(sockfd, SOL_TCP, OPT_RECEIVE_TIMEOUT, &opt_val1, opt_len1);

    if (status != RTCS_OK)

    {

        printf("\n[TCPClient]: Failed to setsockopt for OPT_RECEIVE_TIMEOUT = 0x%x.", status);

        shutdown (sockfd,FLAG_ABORT_CONNECTION);

        return ERROR;

    }

 

    /* bind socket */

    client.sin_family      = AF_INET;

    client.sin_addr.s_addr = INADDR_ANY;

    client.sin_port        = TCP_CLIENT_PORT;   

 

    result = bind(sockfd, &client, sizeof(client));

    if ( result != RTCS_OK )

    {

        printf("\nError, bind() failed with error code %lx", result);

        shutdown(sockfd, FLAG_CLOSE_TX);

        return ERROR;

    }

    printf("Socket Bind Completed %d\n",result);

 

    /* set socket port and address */

    client.sin_port = HTTP_PORT;                                     /* htons not used in MQX */

    client.sin_addr.s_addr = IPADDR(CAADD1, CAADD2, CAADD3, CAADD4); /* MQX specfic macro     */

    client.sin_family = AF_INET;

 

    result = connect(sockfd, &client, sizeof(client));

    if (result != RTCS_OK)

    {

        printf("\nError--connect() failed with error code %lx.\n",result);

    }

    else

    {

        printf("\nConnected to %d.%d.%d.%d, port %d.\n",IPBYTES(client.sin_addr.s_addr), client.sin_port);

    }

 

    /* send command to the server */

    tmpres = send(sockfd, (char *) httpRequestString, sizeof( httpRequestString ),0);

    while ( tmpres < sizeof( httpRequestString ) )

    {

        printf("Part of command sent, sending the rest\n");

        tmpres = send(sockfd, (char*)(httpRequestString+sent), (strlen(httpRequestString)-sent), 0);

 

        if (tmpres == RTCS_ERROR)

        {

            errCode = RTCS_geterror(sockfd);

            printf("\nCan't send query. Error:%x\n",errCode);

            return ERROR;

        }

        sent += tmpres;

    }

    printf("Command send to server:- %s\n",httpRequestString);

 

    _time_delay(100);   

 

    /* ready to receive data from the server */

    memset(recvBuf, 0, sizeof(recvBuf) );

    while ((tmpres = recv(sockfd, recvBuf, sizeof(recvBuf), 0)) > 0)

    {

        numBytes += tmpres;

        recvBuf[tmpres] = 0;     /* for test assuming receiving a html page, this can be printed */

        printf("%s\n",recvBuf);

 

        printf("Packet received of %d Bytes Total Bytes Received %d\n",tmpres,numBytes);

    }

    /* Display error code */

    if ( tmpres == RTCS_ERROR )

    {

        errCode = RTCS_geterror(sockfd);

        printf("\nReceive Error:%x\n",errCode);

    }

    if ( tmpres == 0 )

        printf("No more data to receive from socket\n");

 

    /*shutdown(sockfd, FLAG_CLOSE_TX);*/

    shutdown(sockfd, FLAG_ABORT_CONNECTION);

}

 

The only things you need to change are as follows: -

 

The client address to your Web Server i.e. you can try MQX web server on the same board as a working example, and then try a different web server

 

/* http client address*/

#define CAADD1    172

#define CAADD2    18

#define CAADD3    11

#define CAADD4    11

 

/* For Freescales MQX Web Server Example */

static const char httpRequestString[] = {"\

GET /rtc.html HTTP/1.0\r\n\

Host: 172.18.11.11\r\n\r\n"};

 

Notes:- Access to external web pages (i.e. www.freescale.com) may be block by your companies firewall, best to try internal webpages i.e net work printer etc


You help is very much appreciated…

 

Thanks rick101

 

For back ground info and a link to the twitter example

https://community.freescale.com/thread/301508

 

Updated to add version 2, correct some error handling, added sock time out option, some new results see below

 

Original Attachment has been moved to: httpdsrv_VER2.c.zip
Original Attachment has been moved to: httpdsrv.c.zip

Outcomes