HTML code is never interpreted by the browser

Bonjour

http://oct1.oct2.oct3.oct4/arduino/digital/.../…:5555

I send (not represented in this minimalist code) without problem info
to a browser from my little server on YUN.
The server returns without any problem information to
the browser (here we just return

TOTO </ h1>) but …
the HTML code is never interpreted by the browser !!

I want to say that I did a lot of research about this before posting
but I am very very beginner !

So I’m sending you this very SIMPLE code that deals only with the
part of the work that does not work:

#include <Bridge.h>

#include <BridgeServer.h>
#include <BridgeClient.h>

BridgeServer server;       // le webserver écoute le port 5555 (par défaut)

void setup() 
{

    Serial.begin(9600);

    while(!Serial)
    { }   
    

    Bridge.begin();          
   


    server.noListenOnLocalhost();

    server.begin();

    
      
    Serial.println("Prêt !!");    

}

void loop() 
{

       BridgeClient client = server.accept();

    
       if ( client ) 
       {

                Serial.println("new client");

                String command = client.readStringUntil('/');
                Serial.println(command);
                                  
                client.println("HTTP/1.1 200 OK");
                client.println("Transfer-Encoding: chunked");              
                client.println("Content-Type: text/html; charset=UTF-8");
                client.println("Connection: close");  
                client.println();
                client.println("<!DOCTYPE html>");
                client.println("<html>");                
                client.println("<head><title>Arduino YUN</title></head>");
                client.println("<body><h1>TOTO</h1></body></html>");                   

       }

       // give the web browser time to receive the data
       delay(1);
       // close the connection:
       client.stop();

 
}

I’m on windows 10 et Yun, port série COM7

Merci à tous

Pierre Grenoble

I'm having the same problem.

When I do a wget to my Yun port 5555, TCP tries to open:

Frame 15: 78 bytes on wire (624 bits), 78 bytes captured (624 bits) on interface 0
Ethernet II, Src: 192-168-1-24.local (98:01:a7:a8:6c:75), Dst: DraginoT_1a:0a:ec (a8:40:41:1a:0a:ec)
Internet Protocol Version 4, Src: 192-168-1-24.local (192.168.1.24), Dst: 192.168.1.14 (192.168.1.14)
Transmission Control Protocol, Src Port: 55364, Dst Port: 5555, Seq: 0, Len: 0
Source Port: 55364
Destination Port: 5555
[Stream index: 1]
[TCP Segment Len: 0]
Sequence number: 0 (relative sequence number)
Acknowledgment number: 0
1011 .... = Header Length: 44 bytes (11)
Flags: 0x002 (SYN)
Window size value: 65535
[Calculated window size: 65535]
Checksum: 0x764b [unverified]
[Checksum Status: Unverified]
Urgent pointer: 0
Options: (24 bytes), Maximum segment size, No-Operation (NOP), Window scale, No-Operation (NOP), No-Operation (NOP), Timestamps, SACK permitted, End of Option List (EOL)
TCP Option - Maximum segment size: 1460 bytes
TCP Option - No-Operation (NOP)
TCP Option - Window scale: 6 (multiply by 64)
TCP Option - No-Operation (NOP)
TCP Option - No-Operation (NOP)
TCP Option - Timestamps: TSval 696314497, TSecr 0
TCP Option - SACK permitted
TCP Option - End of Option List (EOL)

But immediately the Yun comes back with a TCP reset:

Frame 17: 54 bytes on wire (432 bits), 54 bytes captured (432 bits) on interface 0
Ethernet II, Src: DraginoT_1a:0a:ec (a8:40:41:1a:0a:ec), Dst: 192-168-1-24.local (98:01:a7:a8:6c:75)
Internet Protocol Version 4, Src: 192.168.1.14 (192.168.1.14), Dst: 192-168-1-24.local (192.168.1.24)
Transmission Control Protocol, Src Port: 5555, Dst Port: 55364, Seq: 1, Ack: 1, Len: 0
Source Port: 5555
Destination Port: 55364
[Stream index: 1]
[TCP Segment Len: 0]
Sequence number: 1 (relative sequence number)
Acknowledgment number: 1 (relative ack number)
0101 .... = Header Length: 20 bytes (5)
Flags: 0x014 (RST, ACK)
Window size value: 0
[Calculated window size: 0]
[Window size scaling factor: -1 (unknown)]
Checksum: 0x0321 [unverified]
[Checksum Status: Unverified]
Urgent pointer: 0
[SEQ/ACK analysis]
[This is an ACK to the segment in frame: 15]
[The RTT to ACK the segment was: 0.009771000 seconds]
[iRTT: 0.009771000 seconds]

Does the Yun Linux need to be tweaked for this to work?

The funny thing is that it looks like Linux IS listening on port 5555....from the Linux console when running the Bridge example sketch:

root@Arduino:~# netstat -l
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 localhost:5700 0.0.0.0:* LISTEN
tcp 0 0 localhost:6571 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:www 0.0.0.0:* LISTEN
...
tcp 0 0 localhost:5555 0.0.0.0:* LISTEN

A local wget to port 5555 on the Yun Linux fails as well...

pierregrenoble:
The server returns without any problem information to
the browser (here we just return

TOTO </ h1>) but …
the HTML code is never interpreted by the browser !!

You are sending HTML headers as part of your response. It looks like you are using BridgeServer/BridgeClient in the same manner as one would use WiFiServer/WiFiClient, and I think that is your problem.

BridgeServer/BridgeClient works very differently from WiFiServer/WiFiClient:

  • WiFiServer/WiFiClient implement a simple network socket. When a request comes in, the WiFiClient receives all of the request headers and the body of the request. In response, the code sends the response headers and response body back through the WiFiClient. This is done because the WiFi Library is talking to a basic network interface that can handle TCP streams, but knows nothing of the HTTP protocol that is riding on top of that stream, therefore the code must handle all of those details.
  • BridgeServer/BridgeClient, on the other hand, handles all of the HTTP protocol details internally. This is because the BridgeClient object is talking to an intelligent process on the Linux side of the Yun. In this case, the Linux side is managing the HTTP protocol, passing only the last part of the URL to the BridgeClient, and expecting only the body of the response in reply.

The intent of the WiFiServer/WiFiClient is to provide a raw TCP socket and the sketch handles the HTTP details. The intent of the BridgeServer/BridgeClient is to easily implement a REST API as demonstrated in the Bridge example. When you make an HTTP request to /arduino/ the Linux side accepts the request, processes the headers, and reads the requested URL. It sees the /arduino/ part of the URL and knows that you want to talk to a BridgeClient in the sketch. It extracts the remaining part of the URL (the part) and passes that to the sketch over the serial port. The sketch can then read the remaining part of the requested URL from the Client object, and write the body of the response. The Linux code then takes the provided body of the response, and wraps it up in an HTTP response by adding its own headers.

Running your code, and looking at the actual response from the Yun, I see:

[color=red]HTTP/1.1 200 OK
Connection: close
Transfer-Encoding: chunked
Content-Type: text/plain
Cache-Control: no-cache
Expires: 0
[/color]

[color=blue]HTTP/1.1 200 OK
Transfer-Encoding: chunked
Content-Type: text/html; charset=UTF-8
Connection: close[/color]

[color=green]<!DOCTYPE html>
<html>
<head><title>Arduino YUN</title></head>
<body><h1>TOTO</h1></body></html>[/color]

The red text contains the headers that were automatically added by the Linux side, the blue text contains the headers that your sketch added, and the green text contains what you intended to be the body of the response. However, the Linux side added its own headers (the red text) including the trailing blank line that shows the end of the headers, therefore everything after the first blank line is treated as the body of the response by the browser. That means that as far as the browser is concerned, the header is the red text and the content type is plain text, so the body of the response (the blue and green text) is displayed as raw text and not processed as HTML.

On the Yun, the Linux side give you a lot more processing power than has been available with the standard ways of adding networking to an Arduino. It requires a different way of thinking. The most efficient way of handling a web server is to implement it on the Linux side. A somewhat simpler way is to take a look at the Temperature Web Panel example - in this case, the Linux side serves up static web pages, and uses the BridgeClient as an AJAX API to retrieve the dynamic content of the page. Note that it’s not explicitly stated on that tutorial page, but you must load the sketch onto your Yun using a network interface, not a USB serial port, in order for the requried web page files to be copied to the Yun.

Personally, I just use the Bottle framework to implement a web server on the Linux side in Python, and let the more powerful Linux processor do the heavy lifting. The sketch just does peripheral I/O and the meat of the processing is on the Linux side.

mpeg2tom:
I’m having the same problem.

I think you have a different problem. But it may be similar in that you are likely using the BridgeClient in a manner which it was not intended.

My understanding is that port 5555 is an internal port used for communications between the sketch and the Linux side. The Linux side receives an HTTP request on port 80, sees that the requested URL starts with /arduino/, so it it makes a connection to port 5555, which gets rerouted over the serial port to the BridgeClient running as part of the sketch.

The Linux side may be listening on port 5555, but it’s listening for a local connection from the sketch, not for a connection from an outside computer. Therefore, the connection attempt is reset.