Page 1 of 2
TCP take 20 minutes to receive a packet
Posted: Fri Nov 20, 2009 3:43 pm
by macpherson
I have a piece of hardware which tries to connect with the NetBurner on port 19777. If I use the sample TCP code as the UserMain all is well. I now create a new task called "Network" and the code takes about 20 minutes to respond to tries from the other hardware. I checked with WireShark and indeed the dst port is 19777. I feel this is some type of priority problem. Can anyone help?
Code: Select all
#define MAIN_PRIO (50)
#define NETWORK_PRIO (30)
void Network (void *pd)
{
IPADDR client_addr;
WORD port;
int fdnet;
//Set up the Listening TCP socket
int fdListen = listen( INADDR_ANY, TCP_PORT_TO_USE, 5 );
if ( fdListen > 0 )
{
setsockoption(fdListen, SO_NONAGLE);
writestring( fdlancon, MTS_WHEN_NOTCONNECTED );
while ( 1 )
{
writestring( fdlancon, "Inside\r\n" ); // serial port
fdnet = accept( fdListen, &client_addr, &port, 0 ); // it gets stuck here waiting
writestring( fdlancon, MTS_WHEN_CONNECTION_OPENED );
sprintf(buf, "fdnet = %d\r\n", fdnet);
writestring( fdlancon, buf );
int tcp_timeout = 0;
while ( fdnet > 0 )
{
fd_set read_fds;
fd_set error_fds;
Many thanks,
Ewan.
Re: TCP take 20 minutes to receive a packet
Posted: Fri Nov 20, 2009 5:43 pm
by seulater
It would be best if you posted the entire code.
Out of curiosity, why do you have your Priority's set so high, bring them down.
Re: TCP take 20 minutes to receive a packet
Posted: Fri Nov 20, 2009 5:51 pm
by lgitlitz
This is definitely a priority problem. You should take a look at the default priorities in ...nburn\include\constants.h. Use ( MAIN_PRIO - 1) for your network task if you want it to be higher priority then user main. Your network task is currently set to prio 30 which is a higher priority then the NetBurner Ethernet, IP and TCP tasks. What confuses me is how you are ever able to retrieve a packet from this task, even after 20 minutes.
-Larry
Re: TCP take 20 minutes to receive a packet
Posted: Fri Nov 20, 2009 7:12 pm
by macpherson
Thanks for your replies.
I used 30 as a priority since MAIN_PRIO -1 did not work either. Here is the complete code.
Code: Select all
void Network (void *pd)
{
IPADDR client_addr;
WORD port;
int fdnet;
//Set up the Listening TCP socket
int fdListen = listen( INADDR_ANY, TCP_PORT_TO_USE, 5 );
if ( fdListen > 0 )
{
setsockoption(fdListen, SO_NONAGLE);
writestring( fdlancon, MTS_WHEN_NOTCONNECTED );
while ( 1 )
{
writestring( fdlancon, "Inside\r\n" );
fdnet = accept( fdListen, &client_addr, &port, 0 );
writestring( fdlancon, MTS_WHEN_CONNECTION_OPENED );
sprintf(buf, "fdnet = %d\r\n", fdnet);
writestring( fdlancon, buf );
int tcp_timeout = 0;
while ( fdnet > 0 )
{
fd_set read_fds;
fd_set error_fds;
FD_ZERO( &read_fds );
FD_SET( fdnet, &read_fds );
//We only check for a waiting socket on the listener when we could do something about it.
if ( tcp_timeout >= OVERIDE_TIMEOUT )
{
FD_SET( fdListen, &read_fds );
}
FD_ZERO( &error_fds );
FD_SET( fdnet, &error_fds );
if ( select( FD_SETSIZE, &read_fds, ( fd_set * ) 0, &error_fds, TCP_WRITE_TIMEOUT ) )
{
if ( FD_ISSET( fdnet, &read_fds ) )
{
char buffer[40];
int n = read( fdnet, buffer, 40 );
// data received here from net
write( fdlancon, buffer, n ); // write to serial
// reply sent here to net
if (buffer[0] == 'H')
write( fdnet, "LAN -- Hi!\r\n", n );
close( fdnet );
fdnet = 0;
writestring( fdlancon, "LAN -- Connection Complete\r\n" );
}
if ( FD_ISSET( fdnet, &error_fds ) )
{
writestring( fdlancon, MTS_WHEN_CONNECTION_CLOSED );
close( fdnet );
fdnet = 0;
writestring( fdlancon, MTS_WHEN_NOTCONNECTED );
}
if ( FD_ISSET( fdListen, &read_fds ) )
{
//We have a new suitor waiting on the listening socket.
// writestring( fdlancon, MTS_WHEN_CONNECTION_OVERIDDEN );
// writestring( fdnet, MTN_WHEN_CONNECTION_OVERIDDEN );
// close( fdnet );
// fdnet = 0;
}
}
else
{
//Select Timed out
tcp_timeout++;
if ( tcp_timeout > TIMEOUT_LIMIT )
{
writestring( fdlancon, MTS_WHEN_CONNECTION_TIMEDOUT );
writestring( fdnet, MTN_WHEN_CONNECTION_TIMEDOUT );
close( fdnet );
writestring( fdlancon, MTS_WHEN_NOTCONNECTED );
fdnet = 0;
}
}//if ( select( FD_SETSIZE, &read_fds, ( fd_set * ) 0, &error_fds, TCP_WRITE_TIMEOUT ) )
}//while ( fdnet > 0 )
}//while ( 1 )
}//if ( fdListen > 0 )
}
I will try anything you suggest.
Ewan.
Re: TCP take 20 minutes to receive a packet
Posted: Fri Nov 20, 2009 7:15 pm
by seulater
30 is still WAY to high. .zip your file and attach it. this was not the whole source code. we need to see the WHOLE thing.
Re: TCP take 20 minutes to receive a packet
Posted: Sat Nov 21, 2009 8:25 am
by macpherson
seulater & lgitlitz,
Here is the whole code. I left everything as-is, even the priority.
Thank you for your assistance.
Ewan.
Re: TCP take 20 minutes to receive a packet
Posted: Sat Nov 21, 2009 12:52 pm
by rnixon
I don't have the answer, but would like to comment on the priorities. From \nburn\include\contatnts.h:
/* Runtime library driver and support task priorities */
#define HTTP_PRIO (45)
#define PPP_PRIO (44)
#define WIFI_TASK_PRIO (41)
#define TCP_PRIO (40)
#define IP_PRIO (39)
#define ETHER_SEND_PRIO (38)
So if you make your task priority lower than TCP, IP and Ethernet, it those tasks will not run unless your task at 30 blocks. So depending on how you wrote your task, it could be a problem. For example, if a task was written that never blocked, no network services would be able to run. The MAIN_PRIO-1 seems like the right thing to do, since it would take precedence over UserMain at prio 50. I'll try to get some time to look at the .zip file for the project, but thought I would add this in case it helps.
Re: TCP take 20 minutes to receive a packet
Posted: Sat Nov 21, 2009 1:24 pm
by macpherson
rnixon,
Thanks, I now understand a bit more about priorities. Yes it does block so that is why everything else runs. I notice that autoupdate has a priority of 15 but it blocks too.
As I said above, I originally started with a priority of (MAIN_PRIO - 1) and ran into the problem. I then fiddled with the priority and got nowhere.
Ewan.
Re: TCP take 20 minutes to receive a packet
Posted: Sat Nov 21, 2009 2:15 pm
by Ridgeglider
See:C:\Nburn\docs\NetworkProgrammersGuide\NNDKProgManual.pdf, the chapter on how tasks work. It's pretty clear... To quote from Chapter 14:
"In a pre-emptive RTOS, the highest priority task ready to run will always run. This is an extremely important point, so I will mention it again: the highest priority task ready to run will always run. This is different than a Windows or Unix system that employs a round-robin approach in which each task will run based on its time slice. If you create a high priority task that can always run, then no lower priority tasks will ever run. Lower priority tasks can only run when a higher priority task blocks on a resource or time delay."
and, further (after the list of functions that block), and keeping in mind that higher priority means lower PRIO number:
"Lets say you have two tasks: A and B. Task A has priority 50 and Task B has priority 51. Since Task A is of higher priority, it will always run (and Task B will never run) unless it [Task A] calls a blocking function. Task B will then run for as long as Task A blocks; this could be 1 second due to a call to OSTimeDly(TICKS_PER_SECOND), until a shared resource is available due to a call to OSSemPend(), or until data is available from a network connection due to a select( ) call. It both tasks were in a blocking state, then the idle task (63) would run."
Re: TCP take 20 minutes to receive a packet
Posted: Sat Nov 21, 2009 5:28 pm
by rnixon
HI,
When you say "it takes 20 minutes to respond", what exactly do you mean? For example, in your code you have the line:
writestring( fdlancon, MTS_WHEN_CONNECTION_OPENED );
When you try to connect from the pc (?) to the netburner, how long between the time you initiate the connection, and when the above status messages appear?