Other Parts Discussed in Thread: SYSBIOS
Dear Team,
I am writing a function to post http requests over TCP using TI-NDK(2.25.00.09). I am able to successfully post HTTP request and get back the response the very first time.
On the second iteration NDK_recv returns 0 with error code (54 -> Connection reset by peer) . I am stuck up on how to handle this. I tried calling NDK_Connect() again in such case but it totally messes up with another set of error codes.
Could you please help on what would be the right way to proceed once i see "Connection reset by peer" error. Should i close and recreate the complete socket again for each http request ?, or is there a best efficient way to handle this. I placed my code below
/************************************ Code Here ****************************************/
#define ETHERNETHTTP_TXDATASIZE 512 // Max size of data to be pushed to server at a time
#define ETHERNETHTTP_RXDATASIZE 512 // Max size of data to be fetched from server at a time
int EthernetHTTPSendSocket_1 = -1;
int EthernetHTTPRecvSocket_1 = -1;
char EthernetHTTPSendData_1[ETHERNETHTTP_TXDATASIZE] = "";
char EthernetHTTPRecvData_1[ETHERNETHTTP_RXDATASIZE] = "";
struct sockaddr_in EthernetHTTPSocketAddr_1;
char EthernetHTTPSocket_Restartrequired = true; // Set bit to TRUE if restart of socket is required
uint32_t CommunicationIP = 0x67546006; // www.evergreeninternet.in [103.84.96.6]
char CommunicationIP_number[17] = "103.84.96.6";
/* Task created from Sysbios task scheduler. Not created dynamically */
void Http_SenddataServer_1_Task()
{
int returnval, err;
struct timeval timeoutvalue;
struct sockaddr_in EthernetHTTP_HOSTAddr;
HTTPRESPONSE_TYPE HttpResponse_Socket1;
int HndlSelfTask = TaskSelf();
int optval;
char ReconnectSocket_flg = true;
memset(&EthernetHTTPSocketAddr_1, 0, sizeof(EthernetHTTPSocketAddr_1));
memset(&EthernetHTTP_HOSTAddr, 0, sizeof(EthernetHTTP_HOSTAddr));
EthernetHTTPSocketAddr_1.sin_family = AF_INET;
EthernetHTTPSocketAddr_1.sin_addr.s_addr = htonl(INADDR_ANY);
EthernetHTTPSocketAddr_1.sin_port = htons(TCPPORT_HTTP);
EthernetHTTP_HOSTAddr.sin_family = AF_INET;
EthernetHTTP_HOSTAddr.sin_addr.s_addr = htonl(INADDR_ANY); /* Host address to be dynamically changed before send */
EthernetHTTP_HOSTAddr.sin_port = htons(TCPPORT_HTTP);
timeoutvalue.tv_sec = 10; // Receive and transmit timeout (10Seconds)
timeoutvalue.tv_usec = 0;
while(1)
{
while(EthernetHTTPSocket_Restartrequired == true)
{
/* Wait until valid IP is obtained */
while(Ethernet_ETHConnStatus.CurrentIP == 0) Task_sleep(1000);
/* Close socket if was already open */
if(EthernetHTTPSendSocket_1 != -1)
{
fdClose(EthernetHTTPSendSocket_1);
fdCloseSession(HndlSelfTask);
}
fdOpenSession(HndlSelfTask);
/* Create socket */
EthernetHTTPSendSocket_1 = NDK_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (EthernetHTTPSendSocket_1 == -1)
{
/* Error handling here */
err = fdError();
}
/* Bind socket */
returnval = NDK_bind(EthernetHTTPSendSocket_1, (struct sockaddr *)&EthernetHTTPSocketAddr_1, sizeof(EthernetHTTPSocketAddr_1));
if(returnval == -1)
{
/* Error handling here */
err = fdError();
}
/* Set socket options */
returnval = NDK_setsockopt(EthernetHTTPSendSocket_1, SOL_SOCKET, SO_KEEPALIVE, &optval, sizeof(optval));
returnval = NDK_setsockopt(EthernetHTTPSendSocket_1, SOL_SOCKET, SO_SNDTIMEO , &timeoutvalue, sizeof(timeoutvalue));
returnval = NDK_setsockopt(EthernetHTTPSendSocket_1, SOL_SOCKET, SO_RCVTIMEO , &timeoutvalue, sizeof(timeoutvalue));
/* Ethernet restart complete */
EthernetHTTPSocket_Restartrequired = false;
ReconnectSocket_flg = true;
}
/* Reconnect socket */
if(ReconnectSocket_flg == true)
{
EthernetHTTP_HOSTAddr.sin_addr.s_addr = htonl(CommunicationIP); // Set Destination host
returnval = NDK_connect(EthernetHTTPSendSocket_1, (struct sockaddr *)&EthernetHTTP_HOSTAddr, sizeof(EthernetHTTP_HOSTAddr));
if(returnval == -1)
{
/* Error handling here */
err = fdError();
if (err == ECONNREFUSED || err == EHOSTDOWN || err == EHOSTUNREACH)
{
EthernetHTTPSocket_Restartrequired = true;
}
else if(err == EISCONN)
{
/* Connection established -> Socket already connected */
ReconnectSocket_flg = false;
}
}
else
{
/* Connection established*/
ReconnectSocket_flg = false;
}
}
/***************************************************************************/
/********************** Send/Receive data to Socket **************/
/* Wait for data ready semaphore */// To be done //
Http_GetConstruct(CommunicationIP_number, "/", EthernetHTTPSendData_1); // Sample data to test
returnval = NDK_send(EthernetHTTPSendSocket_1, EthernetHTTPSendData_1, strlen(EthernetHTTPSendData_1), 0);
if(returnval == -1)
{
err = fdError();
if(err == ENOTCONN) /* 57 -> Socket is not connected */
{
ReconnectSocket_flg = true;
}
}
else
{
/* TX success, get response */
returnval = NDK_recv(EthernetHTTPSendSocket_1, EthernetHTTPRecvData_1, ETHERNETHTTP_RXDATASIZE-1, 0);
err = fdError();
if(err == ECONNRESET) /* 54 -> Connection reset by peer */
{
/*
* Comment to TI: Ends up here on the second interation of the while loop, when sending the HTTP GET for the second time
*/
ReconnectSocket_flg = true;
}
if(err == 0){ Http_ResponseDeconstruct(EthernetHTTPRecvData_1, &HttpResponse_Socket1); }
}
}
}
/*
* Function creates HTTP Get request from data
*
* data -> Raw Data to construct
* datalength -> length of data
* outputdat -> contrcuted HTTP get data
*
*/
void Http_GetConstruct(char* host, char* data, char* outputdat)
{
strcpy(outputdat, "GET ");
strcat(outputdat, data);
strcat(outputdat, " HTTP/1.1");
strcat(outputdat, "\r\nHost: ");
strcat(outputdat, host);
strcat(outputdat, "\r\nUser-Agent: HTTPCli (ARM; TI-RTOS)");
strcat(outputdat, "\r\nConnection: keep-alive");
strcat(outputdat, "\r\n\r\n");
}