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