Page 1 of 1
Making a connection
Posted: Thu Jan 27, 2011 7:44 am
by SeeCwriter
Under some circumstances, the following line of code does not return:
connect(target->ip, 0, port, 1);
If the remote host accepts the connection, the connect() call does return. However if the remote host is listening for a connection but does not accept it, the connect() call does not return. This causes my firmware to appear locked up and there is no way I can recover short of rebooting.
Is there something I can do to prevent the lockup?
Steve
Re: Making a connection
Posted: Thu Jan 27, 2011 12:22 pm
by rnixon
That doesn't sound right. What happens if you repeat that test using the \nburn\examples\tcp\tcpsimple example? Does that lock up as well?
Re: Making a connection
Posted: Thu Jan 27, 2011 2:34 pm
by SeeCwriter
There is no “tcpsimple” example.
The most likely bet would have been “TcpClientSimple”. However, instead of behaving as the title suggests, it sets up a web server and does not accept or receive tcp/ip connections. It’s title is misleading and I find it strange that it appears under tcp examples as it exercises zero tcp/ip features.
The only tcp example that uses connect() is TcpStressTest\app\main(). As I understand the code, it runs a performance analysis depending on an external device to constantly attempt to connect to it and write data…. Not the most ‘simple’ example….
Re: Making a connection
Posted: Thu Jan 27, 2011 2:54 pm
by lgitlitz
The “TcpClientSimple” example does perform as a TCP client but the interface is through a web page hosted by the NetBurner. Try running the exact example and going to the web page. If you want to see the main TCP client code you should look at the "SendMsg" function in clientweb.cpp.
Re: Making a connection
Posted: Thu Jan 27, 2011 3:23 pm
by rnixon
I though you were trying to do a connect(), which is different than accepting or receiving a connection. The TcpClientSimple (sorry for the misname) lets you send data to a tcp server by going to its web page. Here is the relevant code, which calls connect():
/*-------------------------------------------------------------------
Sends a message to the specified host.
------------------------------------------------------------------*/
void SendMsg( IPADDR DestIp, int DestPort, char *msg )
{
iprintf( "Connecting to: " );
ShowIP( DestIp );
iprintf( " : %d\r\n", DestPort );
iprintf( "Attempting to write \"%s\" \r\n", msg );
int fd = connect( DestIp, 0, DestPort, TICKS_PER_SECOND * 5);
if (fd < 0)
{
iprintf("Error: Connection failed\r\n");
}
else
{
int n = write( fd, msg, strlen(msg) );
iprintf( "Wrote %d bytes\r\n", n );
close( fd );
}
}
Re: Making a connection
Posted: Thu Jan 27, 2011 4:33 pm
by SeeCwriter
It doesn’t hang… but curiously nor does it it use the given timeout when it fails to connect
int fd = connect( DestIp, 0, DestPort, TICKS_PER_SECOND * 5);
…produces no timeout whatsoever; it indicates failure right after announcing the attempt to connect. This is a different result than my application experienced, but still incorrect.
To further experiment, I put a canned SendMsg() call in the main user loop, to run at 1 sec intervals. Again, I saw little or no delay between the connection attempt and the failure notification.
Then I modified the main loop, increasing the time delay to 5 seconds per loop.
OSTimeDly( 5*TICKS_PER_SECOND );
Ahah, now I am getting 5 second timeouts on the web-initiated connect() call. But still zero timeout duration on the canned call in my main loop.
Conclusion: there is an undocumented interaction between OSTimeDly() and the timeout used for the connect() call. If the connect occurs in the main user task, the timeout value is effectively undefined. If the connect occurs in a ‘background’ (priority) task, the timeout is dependant upon the main task periodically releasing control to the OS for large blocks of time.
Side note: the web page ignores whatever you type in for the destination port and always attempts port 2000 according to the print statements on the serial port. This is reflected on the web page which instantly reverts to port 2000 no matter what you type in. In MTTTTY it says “error reading post data: tfTestPort”.
Re: Making a connection
Posted: Thu Jan 27, 2011 6:27 pm
by lgitlitz
The timeout parameter is defined as the amount of time to wait for a response from the server before the attempted connection is abandoned as a timeout error. There are many other errors that can occur which will return much quicker. For example the server may be actively denying the attempt to connect to that socket. When this happens there is no timeout condition since the server responded to the connection request. The connect function will return an error immediately after receiving the denial from the server.
You should try to connect to the server using a PC and telnet. I would also run wireshark on the server to capture the network communication. You will then be able to get a much better picture of what is happening when the connect call fails.
The port switching error in the example has been corrected in the latest beta that is available. The variable in clientweb.cpp should be tfDestPortNum instead of tfDestPort.