I have a customized version of WebServer that generally works well, but sometimes when I click a link or button in the browser to go to another page, I see a "waiting to connect..." message on the browser status line. The "core" of my WebServer Update method, lifted from the standard WebServer library, and is called on each pass through loop(), is below.
void WebServer::Update(void)
{
EthernetClient client = pMyEthernetServer->available();
if (client)
{
// now client is connected to arduino we need to extract the
// following fields from the HTTP request.
BUFFER requestContent; // Request content as a null-terminated string.
MethodType eMethod = readHttpRequest(client, requestContent);
// Parse request and send content here
// give the web browser time to receive the data
delay(1);
client.stop();
}
}
Keep in mind, I know squat about web servers. What little I now know has been learned in the process of cobbling WebServer for this one application. However, I note the client.stop() at the very end, and wonder if this is correct behavior for a web server in the middle of an interactive session? Is there a good reason to close the connection, and not leave it open to process further requests? Could this have anything to do with why my server is sometimes unresponsive for as much as 10-20 seconds at a time? The browser will always re-connect, eventually, but it may take several refresh attempts before it does. Other times, I can go page-to-page with reckless abandon, and all is fine. I haven't yet attempted to debug this, but was just curious whether this one aspect of the code is really right.
The specific code is not important. This is a question about the correct/expected server response to a browser GET request. The one and only question is:
Is it correct/expected for a web server to do a EthernetClient.stop() immediately after sending the content? Seems wrong to me, but what do I know... I would expect this if UDP were being used, but it is my clear understanding that HTTP does no use UDP.
That depends on the Connection parameter in the http header.
"Connection: close" = close after all packets transmitted
"Connection: keep-alive" = keep the connection open http://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html
RayLivingston:
Is it correct/expected for a web server to do a EthernetClient.stop() immediately after sending the content? Seems wrong to me, but what do I know...
It's absolutely correct.
With "HTTP 0.9" and "HTTP 1.0" requests, this behavior is a must for HTTP:
client establishs connection with server
client sends request
server answers request
server closes connection
Although with "HTTP 1.1" the request may contain an additional header line, that the client wants the connection to "keep-alive", this is just a friendly wish from the client. It's solely up to the server if keeps the connection established or not. So even in that case its absolutely correct to shut down the connection with client.stop().
If you are not on a multitasking operating system, there are only rare cases when it would be of any use to keep the connection open. For example if you want to handle a lot of requests between the same client and the same server in a very short time.
But as you have no multitasking operating system on an Arduino, you most likely will block out all other connections while you keep alive one single connection. If you like, you can. SurferTim has posted links to some of the RFC documents how to handle keep-alive connections. But I don't find it very useful.
Actually, I think I can handle 4 simultaneous persistent connections with my Mega 2560 and an ethernet shield. Here is the basic code with no server stuff connected yet. It can be used for a tcp (telnet or http) persistent connection. http://playground.arduino.cc/Code/Telnet
OK, so the stop() is ok. Now I have to do some debugging to figure out why, sometimes, the browser has trouble re-opening the connection. It seems to sometime lose the ability to even find the Arduino, even though it is still there, still connected, and, other than Ethernet, working perfectly. Once earlier today, when the browser was stuck waiting, I could no longer even ping the Arduino. After doing nothing more than waiting maybe 45 seconds, it suddenly re-appeared, and started working fine.