Author Topic: Trying to get some TCP work done...  (Read 9404 times)

Offline Marc VDH

  • Newbie
  • *
  • Posts: 11
    • View Profile
    • iMetaf Weather Station
Trying to get some TCP work done...
« on: October 27, 2009, 06:28:45 PM »
I'm currently trying to download some HTTP data from the internet using the uTasker. I used the TCP tutorial that was posted here a while ago as a reference, together with the NTP client code from the demo application.

Definitions...
Code: [Select]
#define METAF_TCP_PORT 8080
#define MAX_DATA_LEN 500
typedef struct stTCP_MESSAGE
{
TCP_HEADER     tTCP_Header;                    // reserve header space
unsigned char  ucTCP_Message[MAX_DATA_LEN];    // data payload space
} TCP_MESSAGE;

const char postData[] = "station_ids=EBAW&std_trans=standard&chk_metars=on&hoursStr=most+recent+only&chk_tafs=on&submitmet=Submit";
static TCP_MESSAGE MetafData;
USOCKET Metaf_TCP_socket;
static unsigned char ucRemoteIP[IPV4_LENGTH] = {204,227,127,34};

My code first obtains a free socket and then performs a connect to the server. So far it's all working fine.
When the connection is successful, the data that is to be sent is created and sent using fnSendTCP. Tracing the code indicates that the data transmission is successful.

Connecting and sending data...
Code: [Select]
extern void fnMETAF(TTASKTABLE *ptrTaskTable)
{
char printstring[2048];

Metaf_TCP_socket = fnGetTCP_Socket(TOS_MINIMISE_DELAY, TCP_DEFAULT_TIMEOUT, fnMetafListener);
if (Metaf_TCP_socket >= 0)
{
fnTCP_Connect(Metaf_TCP_socket, ucRemoteIP, METAF_TCP_PORT, 0, 0);

strcpy ((char*)MetafData.ucTCP_Message, "POST /metars/index.php HTTP/1.1\r\n");
strcat ((char*)MetafData.ucTCP_Message, "Content-Type: application/x-www-form-urlencoded\r\n");
strcat ((char*)MetafData.ucTCP_Message, "User-Agent: Mozilla/2.0 (compatible; WS4.9e.667)\r\n");
strcat ((char*)MetafData.ucTCP_Message, "Host: adds.aviationweather.gov\r\n");
sprintf (printstring, "Content-Length: %d\r\n", strlen(postData));
strcat ((char*)MetafData.ucTCP_Message, printstring);
strcat ((char*)MetafData.ucTCP_Message, "Cache-Control: no-cache\r\n\r\n");
strcat ((char*)MetafData.ucTCP_Message, postData);

if (fnSendTCP(Metaf_TCP_socket, (unsigned char *)&MetafData, strlen((char*)MetafData.ucTCP_Message), TCP_FLAG_PUSH) > 0)
{
strcpy (printstring, (char*)MetafData.ucTCP_Message);    // just some code to put a breakpoint on
}
}
}

The listener code is never reached. Wireshark doesn't indicate a received packet either.

Listener code...
Code: [Select]
static int fnMetafListener(USOCKET Socket, unsigned char ucEvent, unsigned char *ucIp_Data, unsigned short usPortLen)
{
char printstring[2048];
switch (ucEvent)
{
case TCP_EVENT_ARP_RESOLUTION_FAILED:
break;

case TCP_EVENT_DATA:
// process data
strcpy (printstring, (char*)ucIp_Data);
break;

case TCP_EVENT_CLOSE:
case TCP_EVENT_CLOSED:
case TCP_EVENT_ABORT:                                                // no connection was established
break;
}
return APP_ACCEPT;
}

I have a windows program that sends the same request to the same server and processes the same data. The lines in the trace window that indicate the transmission and reception of the relevant data in Wireshark are all in green. The lines that come from the uTasker are all grey though. Also, the packets that come from the uTasker don't contain the data that I'm trying to send and don't have the PUSH flag set either.

There is obviously something not being done right here. Any help is appreciated!  :)

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3237
    • View Profile
    • uTasker
Re: Trying to get some TCP work done...
« Reply #1 on: October 27, 2009, 09:55:28 PM »
Hi Marc

I think that the main problem is that you are calling fnTCP_connect() immediately followed by fnSendTCP().
The fnTCP_connect() will start the connection process - which may start with first ARP resolution before it sends the TCP SYN. The connection will generally require ms to s depending on the destination and distances involved.

Therefore you need first to wait for the connection to complete, which will be signaled by the event TCP_EVENT_CONNECTED.

Then you can start sending data. Note also that you may get a TCP_EVENT_REGENERATE, indicating that you need to resent the last data packet (this may happen when a transmission really times out but may also be due to the fact that the ARP resolution needed to be started again - can happen when a connection is idle for some time and the ARP table entries time out).

Check that the connection is first correctly established and then you shouldn't have difficulties sending data.

Regards

Mark

Offline Marc VDH

  • Newbie
  • *
  • Posts: 11
    • View Profile
    • iMetaf Weather Station
Re: Trying to get some TCP work done...
« Reply #2 on: October 29, 2009, 08:54:18 PM »
Great, seems to work now, thanks! :) It looks like, after the connection is attempted, all the work has to be done in the listener routine.

Another question:
With a TCP transmission it is possible for the data packets to arrive out-of-order. How is this handled by the uTasker?
« Last Edit: October 29, 2009, 09:50:10 PM by Marc VDH »

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3237
    • View Profile
    • uTasker
Re: Trying to get some TCP work done...
« Reply #3 on: October 30, 2009, 01:00:54 AM »
Hi Marc

I think that you mean that the receptions arrive out of order, when seen from the receiver's side. in this case out-of-order frames would have unexpected sequence numbers and these would be ignored. This provokes a retransmission, after which it is accepted since it then arrives in-order.

If this were not performed it would require the frames to be buffered somewhere and then tried again after in-order frames have been handled. In most small-memory projects the buffer space could become a problem and so the simplistic approach is taken. I don't know how often out-of-order frames actually arrive but there are no known practical problems...

Regards

Mark