/********************************************************************************** * libwebsockets libwebsockets-webserver.c hacking * 说明: * 找点libwesockets的资料看看,主要是为后续使用做准备。 * * 2017-6-9 深圳 龙华樟坑村 曾剑锋 *********************************************************************************/ 一、参考文档: 1. libwebsockets如何使用? https://www.zhihu.com/question/57474416 2. libwebsockets: Simple HTTP server https://medium.com/@martin.sikora/libwebsockets-simple-http-server-2b34c13ab540 3. martinsik/libwebsockets-webserver.c https://gist.github.com/martinsik/3216369 4. martinsik/index.html https://gist.github.com/martinsik/3654228 二、代码解读: #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <libwebsockets.h> // 浏览器websocket访问的回调函数 static int callback_http(struct libwebsocket_context *context, struct libwebsocket *wsi, enum libwebsocket_callback_reasons reason, void *user, void *in, size_t len) { switch (reason) { // 头文件链接描述,出了作为Server会喷出一行连接建立以外,这里不进行任何处理 // http://git.warmcat.com/cgi-bin/cgit/libwebsockets/tree/lib/libwebsockets.h#n260 case LWS_CALLBACK_CLIENT_WRITEABLE: printf("connection established "); // 头文件链接描述 // http://git.warmcat.com/cgi-bin/cgit/libwebsockets/tree/lib/libwebsockets.h#n281 case LWS_CALLBACK_HTTP: { char *requested_uri = (char *) in; printf("requested URI: %s ", requested_uri); // 喷出访问的URL // uri为"/"访问,直接给出hello world if (strcmp(requested_uri, "/") == 0) { void *universal_response = "Hello, World!"; // http://git.warmcat.com/cgi-bin/cgit/libwebsockets/tree/lib/libwebsockets.h#n597 libwebsocket_write(wsi, universal_response, strlen(universal_response), LWS_WRITE_HTTP); break; } else { // try to get current working directory char cwd[1024]; char *resource_path; if (getcwd(cwd, sizeof(cwd)) != NULL) { // allocate enough memory for the resource path // 动态分配路径存储空间 resource_path = malloc(strlen(cwd) + strlen(requested_uri)); // join current working direcotry to the resource path // 合成资源路径 sprintf(resource_path, "%s%s", cwd, requested_uri); printf("resource path: %s ", resource_path); // 获取文件扩展名 char *extension = strrchr(resource_path, '.'); char *mime; // choose mime type based on the file extension // 设置扩展类型 if (extension == NULL) { mime = "text/plain"; } else if (strcmp(extension, ".png") == 0) { mime = "image/png"; } else if (strcmp(extension, ".jpg") == 0) { mime = "image/jpg"; } else if (strcmp(extension, ".gif") == 0) { mime = "image/gif"; } else if (strcmp(extension, ".html") == 0) { mime = "text/html"; } else if (strcmp(extension, ".css") == 0) { mime = "text/css"; } else { mime = "text/plain"; } // by default non existing resources return code 400 // for more information how this function handles headers // see it's source code // http://git.warmcat.com/cgi-bin/cgit/libwebsockets/tree/lib/parsers.c#n1896 libwebsockets_serve_http_file(wsi, resource_path, mime); } } // close connection // 关闭连接 libwebsocket_close_and_free_session(context, wsi, LWS_CLOSE_STATUS_NORMAL); break; } default: printf("unhandled callback "); break; } return 0; } /* list of supported protocols and callbacks */ // 配置协议以及其回调函数 static struct libwebsocket_protocols protocols[] = { /* first protocol must always be HTTP handler */ { "http-only", /* name */ callback_http, /* callback */ 0 /* per_session_data_size */ }, { NULL, NULL, 0 /* End of list */ } }; int main(void) { // server url will be http://localhost:7681 int port = 8080; const char *interface = NULL; struct libwebsocket_context *context; // we're not using ssl const char *cert_path = NULL; const char *key_path = NULL; // no special options int opts = 0; // create libwebsocket context representing this server // 创建上下文 context = libwebsocket_create_context(port, interface, protocols, libwebsocket_internal_extensions, cert_path, key_path, -1, -1, opts); if (context == NULL) { fprintf(stderr, "libwebsocket init failed "); return -1; } printf("starting server... "); // infinite loop, the only option to end this serer is // by sending SIGTERM. (CTRL+C) while (1) { libwebsocket_service(context, 50); // libwebsocket_service will process all waiting events with their // callback functions and then wait 50 ms. // (this is single threaded webserver and this will keep // our server from generating load while there are not // requests to process) } libwebsocket_context_destroy(context); return 0; }