Multithreaded Dumb HTTP Server

Overview

See Dumb HTTP server (multi-threaded) for the original description.

Requirements

  • This sample application negotiate IPv4 address from a DHCPv4 server running everywhere in your local network.

  • The 10/100 Ethernet MAC already configured in RMII/MII mode with MDIO using the &mac devicetree label.

Building and Running

Build and flash Multithreaded Dumb HTTP Server as follows:

Build the Zephyr version of the sockets/dumb_http_server_mt application like this:

west build -b magpie_f777ni -p -d build/dumb_http_server_mt-magpie_f777ni zephyr/samples/net/sockets/dumb_http_server_mt -- -DCONFIG_NET_UDP=y -DCONFIG_NET_DHCPV4=y
west flash -d build/dumb_http_server_mt-magpie_f777ni

Once DHCPv4 client address negotiation completed with server, details are shown on the console like this:

*** Booting Zephyr OS build v4.1.0 ***
[00:00:00.011,000] <inf> net_config: Initializing network
[00:00:00.011,000] <inf> net_config: Waiting interface 1 (0x200217e8) to be up...
[00:00:00.512,000] <inf> net_config: Interface 1 (0x200217e8) coming up
[00:00:00.512,000] <inf> net_config: IPv4 address: 192.0.2.1
[00:00:00.512,000] <inf> net_config: Running dhcpv4 client...
[00:00:00.614,000] <inf> net_config: IPv6 address: fd9c:33d7:ba99:0:280:e1ff:fee1:9a39
[00:00:00.614,000] <inf> net_dumb_http_srv_mt_sample: Network connected
[00:00:00.615,000] <dbg> net_dumb_http_srv_mt_sample: process_tcp6: Waiting for IPv6 HTTP connections on port 8080, sock 3
[00:00:00.615,000] <dbg> net_dumb_http_srv_mt_sample: process_tcp4: Waiting for IPv4 HTTP connections on port 8080, sock 4
[00:00:08.531,000] <inf> net_dhcpv4: Received: 192.168.10.197
[00:00:08.531,000] <inf> net_config: IPv4 address: 192.168.10.197
[00:00:08.531,000] <inf> net_config: Lease time: 28800 seconds
[00:00:08.532,000] <inf> net_config: Subnet: 255.255.255.0
[00:00:08.532,000] <inf> net_config: Router: 192.168.10.1

Now the sample was starting, it expects connections at 192.168.10.197, port 8080. The easiest way to connect is by opening a following URL in a web browser: http://192.168.10.197:8080/

You should see a page with a sample content about Zephyr (captured at a particular time from Zephyr’s web site, note that it may differ from the content on the live Zephyr site).

What is Zephyr™ Project?

The following console output can be observed parallel to the action of the web browser from the host:

[00:00:34.613,000] <dbg> net_dumb_http_srv_mt_sample: process_tcp: [5] Connection #1 from 192.168.10.100
[00:00:34.613,000] <dbg> net_dumb_http_srv_mt_sample: process_tcp: [6] Connection #2 from 192.168.10.100

Alternatively, a tool like curl can be used:

$ curl http://192.168.10.197:8080/

The following raw HTML output should appear:

<html> <head> <style> body { background-color: #f3f5f6; font-family: “sans-serif”; } </style> </head>

<body>

<p style=”color: red”> Warning: this is a content sample. Proceed to <a href=”https://www.zephyrproject.org/learn-about”>Zephyr About page</a> for up to date information. </p>

<h1>What is Zephyr™ Project?</h1>

<table width=”50%”> <tr><td> <p> The Zephyr™ Project, is a Linux Foundation hosted Collaboration Project, an open source collaborative effort uniting leaders from across the industry to build a best-in-breed small, scalable, real-time operating system (RTOS) optimized for resource constrained devices, across multiple architectures. The Zephyr Project’s goal is to establish a neutral project where silicon vendors, OEMs, ODMs, ISVs, and OSVs can contribute technology to reduce the cost and accelerate time to market for developing the billions of devices that will make up the majority of the Internet of Things </p>

<p> The Zephyr Project is perfect for building simple connected sensors, LED wearables, up to modems and small IoT wireless gateways. Because the Zephyr OS is modular and supports multiple architectures, developers are able to easily tailor an optimal solution to meet their needs. As a true open source project, the community can evolve the project to support new hardware, developer tools, sensor and device drivers. Enhancements in security, device management capabilities, connectivity stacks and file systems can be easily implemented. </p>

<p> The Zephyr kernel is derived from Wind River’s commercial VxWorks Microkernel Profile for VxWorks. Microkernel Profile has evolved over 20 years from DSP RTOS technology known as Virtuoso. The RTOS has been used in several commercial applications including satellites, military command and control communications, radar, telecommunications and image processing. The most recent example of the technology’s success is the successful Philae Landing on Comet Churyumov–Gerasimenko and the accompanying Rosetta Orbiter. </p> </td></tr>

</table>

</body></html>

Finally, you can run an HTTP profiling/load tool like Apache Bench (ab) against the server:

$ ab -r -g dumb_http_server_mt_ab.csv -t 60 -c 1000 http://192.168.10.197:8080/ | \
       tee dumb_http_server_mt_ab.log && gnuplot dumb_http_server_mt_ab.p

The -n parameter specifies the number of HTTP requests to issue against a server. The -c parameter specifies the number of multiple requests to perform at a time. An example result would looks like:

Apache HTTP server benchmarking result
This is ApacheBench, Version 2.3 <$Revision: 1843412 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 192.168.10.197 (be patient)


Server Software:
Server Hostname:        192.168.10.197
Server Port:            8080

Document Path:          /
Document Length:        2084 bytes

Concurrency Level:      1000
Time taken for tests:   60.001 seconds
Complete requests:      15255
Failed requests:        9520
   (Connect: 0, Receive: 13, Length: 9494, Exceptions: 13)
Total transferred:      12328540 bytes
HTML transferred:       12005924 bytes
Requests per second:    254.25 [#/sec] (mean)
Time per request:       3933.177 [ms] (mean)
Time per request:       3.933 [ms] (mean, across all concurrent requests)
Transfer rate:          200.66 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        1  176 1360.5      4   31613
Processing:     0   30 158.5      7    9201
Waiting:        0   13  76.6      0    3205
Total:          3  206 1390.2     12   32852

Percentage of the requests served within a certain time (ms)
  50%     12
  66%     16
  75%     19
  80%     21
  90%    215
  95%   1029
  98%   2066
  99%   3267
 100%  32852 (longest request)

GNUplot script:

set terminal png size 600
set output "dumb_http_server_mt_ab.png"
set title "1000 concurrent requests for 60 seconds"
set size ratio 0.6
set grid y
set xlabel "requests"
set ylabel "response time (ms)"
plot "dumb_http_server_mt_ab.csv" using 9 smooth sbezier with lines title "http://192.168.10.197:8080/"