Exploring the Mongoose Framework
mongoose
is a lightweight, cross-platform C/C++ networking library that helps us quickly set up a web server, handle HTTP requests, and implement WebSocket communication, among other features. Its simple interface and rich functionality make it an ideal choice for beginners in C++ web programming. Before using mongoose
, ensure that it has been successfully integrated into your development environment. You can obtain the source code from the official GitHub repository and follow the documentation for compilation and configuration.
Setting Up a Simple Web Server
The following code demonstrates how to use mongoose
to set up a simple web server that returns a fixed response when a client accesses it.
#include "mongoose.h"
#include <iostream>
// Event handler function
static void ev_handler(struct mg_connection *c, int ev, void *ev_data) {
if (ev == MG_EV_HTTP_REQUEST) {
struct mg_http_request *request = (struct mg_http_request *) ev_data;
mg_printf(c, "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n\r\n");
mg_printf(c, "Welcome to my C++ Web server!");
}
}
int main() {
struct mg_mgr mgr;
struct mg_connection *c;
// Initialize manager
mg_mgr_init(&mgr, nullptr);
// Bind port and set event handler
c = mg_bind(&mgr, "8080", ev_handler);
if (c == nullptr) {
std::cerr << "Failed to create listener" << std::endl;
return 1;
}
// Set HTTP protocol
mg_set_protocol_http_websocket(c);
std::cout << "Web server is running on port 8080" << std::endl;
// Event loop
for (;;) {
mg_mgr_poll(&mgr, 1000);
}
// Free resources
mg_mgr_free(&mgr);
return 0;
}
In this code, we define an event handler function ev_handler
that returns a simple welcome message to the client when an HTTP request arrives. We bind the server to port 8080 using the mg_bind
function and start an event loop to continuously listen for requests.
Handling Dynamic Requests
To enable the server to handle requests for different paths, we can extend the event handler function.
#include "mongoose.h"
#include <iostream>
#include <string>
static void ev_handler(struct mg_connection *c, int ev, void *ev_data) {
if (ev == MG_EV_HTTP_REQUEST) {
struct mg_http_request *request = (struct mg_http_request *) ev_data;
std::string uri(request.uri.p, request.uri.len);
if (uri == "/about") {
mg_printf(c, "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n\r\n");
mg_printf(c, "This is an about page.");
} else if (uri == "/contact") {
mg_printf(c, "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n\r\n");
mg_printf(c, "Contact information: [email protected]");
} else {
mg_printf(c, "HTTP/1.1 404 Not Found\r\n");
}
}
}
int main() {
struct mg_mgr mgr;
struct mg_connection *c;
mg_mgr_init(&mgr, nullptr);
c = mg_bind(&mgr, "8080", ev_handler);
if (c == nullptr) {
std::cerr << "Failed to create listener" << std::endl;
return 1;
}
mg_set_protocol_http_websocket(c);
std::cout << "Web server is running on port 8080" << std::endl;
for (;;) {
mg_mgr_poll(&mgr, 1000);
}
mg_mgr_free(&mgr);
return 0;
}
In this version, the event handler function returns different content based on the requested URI path. If the path is /about
, it returns information about the page; if the path is /contact
, it returns contact information; other paths return a 404 Not Found.