We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
Hi all,
I am implementing a web server using the RL TCP/IP stack. I'm using a web server from Allegro (RomPager), as opposed to the Keil HTTP server, because I required SSL/TSL.
I've got to the stage where the web server works through the Keil TCP/IP stack, and even SSL works.
When the web server wants to close a connection that exists over a socket, I make use of the tcp_close() function. From reading the documentation and from reading other posts and FAQs from this site, I understand fully that the procedure is as follows:
1. Call tcp_close(). It should return __TRUE.
2. Allow time for the listener socket callback function to be called, with the value TCP_EVT_CLOSE.
3. Then, ensure the socket has definitely finished closing by calling tcp_get_state, and ensuring the result is either TCP_STATE_CLOSED or TCP_STATE_LISTEN.
Here's the problem: If the browser is Internet Explorer 7, a call to tcp_close() NEVER results in a TCP_EVT_CLOSE event at the callback function. If my memory serves me right, a call to tcp_get_state always results in TCP_STATE_FINW2. After a few seconds though (maybe 10 or 20 seconds), Internet Explorer 7 seems to abort the connection. Once IE7 has aborted the connection, then the socket definitely does return to TCP_STATE_LISTEN.
If I use Firefox, the socket DOES close properly. I call tcp_close(), and the callback function is quickly called with a TCP_EVT_CLOSE event, and my socket becomes a listener again immediately.
I am new to network programming and I have not yet used a network sniffer to try to see what's going on. But that's what I'm going to try to do next. If anyone has any suggestions in the meantime about this, I would be extremely grateful for suggestions.
Regards
Trevor
Thanks for your thoughts and ideas though - it's much appreciated. It would be nice to use a 'nicer' solution if one exists.
The Keil stack is a strange beast really and took me a bit of time to interface to the web server I'm using, which expects to see a BSD-like interface. Furthermore it's the first TCP/IP work I've ever done and I've not actually done any WinSock programming at all, although I'm familiar with the basics.
For starters I had to code a simple memory pool to store receive packets as they come in. The Keil stack just returns received packets to a callback function (so receive packets must be dealt with there and then; Keil have implemented a flow control option to make things easier). I then provide the buffers to the server through a 'recv()'-style wrapper function, and free up the buffers when the server has transmitted its reply.
The other concept that I had to get my head around was how listener sockets are used. With a conventional stack, I believe that you only ever need to create one listener socket, and then calling accept() will automatically assign you a new socket for each new connection. But with the Keil stack, a listener socket becomes the socket over which the connection is made. So you have to set up as many listener sockets at the start for as many connections as you'll ever want.
Trev
Trevor,
Thanks for your interesting post.
You wrote:
The Keil stack just returns received packets to a callback function (so receive packets must be dealt with there and then;...
Well, I can only guess that Keil did that in order to save RAM footprint while preventing the need to re-compile the stack if buffer sizes change. But I have no idea why they deviated from the common socket interface.