C语言socket HTTP Server hello world程序(Ubuntu Linux 24.04环境)

2024-06-20 07:28

本文主要是介绍C语言socket HTTP Server hello world程序(Ubuntu Linux 24.04环境),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本程序实现的是一个能返回hello world的http server, 也只能返回hello world,作为C语言http server开发的一个起步阶段。

/*
编译生成可执行程序(Ubuntu Linux 24.04)
# gcc ./socket_server.c -o socket_server
# scp socket_server root@idealand.space:/root/code/buda/c
启动http server
# ./socket_server http_single_thread
启动client message display
# ./socket_server show_client_messages查看防火墙的状态:(国内的云服务器80,443,8080,8443是备案端口,必须备案以后才能从外网访问,注意避免使用)
# ufw status
# ufw allow 8888
查看端口是否被其它程序占用
# sudo apt lsof
# lsof -i:8888
*/#include <stdio.h>      // printf
#include <string.h>	    // strlen(char*)
#include <unistd.h>     // close(int file_descriptor): close socket
#include <sys/socket.h> // socket(), bind(), accept(), etc
#include <netdb.h>      // gethostbyname(char* domain_name)
#include <arpa/inet.h>	// long inet_addr(char* ip_address) : convert ip string to long int format#define SERVER_LISTEN_PORT 8888
#define SOCK_BUF_SIZE 10241
#define SOCK_BUF_SIZE1 10240 // subtract 1 for the null terminator at the buf end
#define SOCK_CONN_QUEUE_MAX 3
#define MODE_show_client_messages "show_client_messages"
#define MODE_http_single_thread "http_single_thread"
#define HTTP_HEAD "HTTP/1.1 200 OK\n\
Server: buda\n\
Content-Type: text/html\n\
Content-Length: %ld\n\
\n\
%s"enum MODE
{SHOW_CLIENT_MESSAGES=1, HTTP_SINGLE_THREAD
};typedef int (*FUN_process_connection_sock)(int sock, char* buffer, int buf_size); int make_http_response(char* buf, int buf_size)
{char* content="<!DOCTYPE html><body>hello world</body></html>";int len=sprintf(buf, HTTP_HEAD, strlen(content) , content); buf[len]=0;return len;
}// server waits for messages from client, and display messages in server console
// the listen socket and connection sockets work in the same single thread, so the queued clients may be blocked for a very long time.
int show_client_messages_single_thread(int sock, char* buffer, int buf_size)
{long recv_size=0, buf_size1=buf_size-1;while((recv_size = recv(sock, buffer, buf_size1, 0))>0){if(recv_size<0) { printf("receive from client failed\n"); return -1;}buffer[recv_size]=0; // set string endprintf("received %ld bytes data: \n%s\n", recv_size, buffer);}
}// server waits for a message from client, response it, and close the connection, then wait for the next client to connect
// the listen socket and connection sockets work in the same single thread
int http_single_thread(int sock, char* buffer, int buf_size)
{int r=0;long recv_size=0, buf_size1=buf_size-1;recv_size = recv(sock, buffer, buf_size1, 0);if(recv_size<0) { printf("receive from client failed\n"); return -1;}buffer[recv_size]=0; // set string endprintf("received %ld bytes data: \n%s\n", recv_size, buffer);int send_size = make_http_response(buffer, buf_size);r = send(sock, buffer, send_size, 0);if(r>0) printf("[sent to client]\n%s\n[end of sent]\n", buffer);return r;
}int main(int argc, char * argv[])
{int r=0; enum MODE mode=SHOW_CLIENT_MESSAGES; FUN_process_connection_sock fun_sock=show_client_messages_single_thread;if(argc>=2){if(strcmp(MODE_http_single_thread, argv[1])==0) { mode=HTTP_SINGLE_THREAD; fun_sock=http_single_thread; printf("server work in http_single_thread mode\n"); }}if(mode==SHOW_CLIENT_MESSAGES) printf("server work in client_messages_single_thread mode\n");int listen_sock, sock;struct sockaddr_in server_addr, client_addr;socklen_t addrlen = sizeof(struct sockaddr_in);int client_count=0;	char *client_ip; int client_port;char buffer[SOCK_BUF_SIZE] = { 0 };long send_size=0;if ((listen_sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("create server listen socket failed\n"); goto fail; 	}printf("create server listen socket succeed\n");server_addr.sin_family = AF_INET; // IPv4server_addr.sin_addr.s_addr = INADDR_ANY;	// 监听所有本地IP地址server_addr.sin_port = htons(SERVER_LISTEN_PORT);if (bind(listen_sock, (struct sockaddr*)&server_addr, addrlen) == -1) { perror("server listen socket bind to ip:port failed\n"); goto fail_close; }printf("bind server listen socket to port %d succeed\n", SERVER_LISTEN_PORT);if (listen(listen_sock, SOCK_CONN_QUEUE_MAX) == -1) { perror("server socket start listening failed\n"); goto fail_close; }printf("server socket starts listening ...\n");while((sock	= accept(listen_sock, (struct sockaddr*)&client_addr,	&addrlen)) > 0){			client_count++;client_ip = inet_ntoa(client_addr.sin_addr); client_port = ntohs(client_addr.sin_port);printf("%d --------------- \nserver socket accepted a client connection:  %s:%d ---------------\n", client_count, client_ip, client_port);// if(set_socket_options(sock) == -1) goto end_close_client;if(fun_sock(sock, buffer, SOCK_BUF_SIZE) < 0) goto end_close_client;end_close_client: close(sock);printf("waiting for next client ...\n");}close(listen_sock); goto succeed;fail_close: close(listen_sock); goto fail;succeed: return r;fail: r=1; return r;
}

这篇关于C语言socket HTTP Server hello world程序(Ubuntu Linux 24.04环境)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1077478

相关文章

通过Docker容器部署Python环境的全流程

《通过Docker容器部署Python环境的全流程》在现代化开发流程中,Docker因其轻量化、环境隔离和跨平台一致性的特性,已成为部署Python应用的标准工具,本文将详细演示如何通过Docker容... 目录引言一、docker与python的协同优势二、核心步骤详解三、进阶配置技巧四、生产环境最佳实践

Nginx部署HTTP/3的实现步骤

《Nginx部署HTTP/3的实现步骤》本文介绍了在Nginx中部署HTTP/3的详细步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学... 目录前提条件第一步:安装必要的依赖库第二步:获取并构建 BoringSSL第三步:获取 Nginx

防止Linux rm命令误操作的多场景防护方案与实践

《防止Linuxrm命令误操作的多场景防护方案与实践》在Linux系统中,rm命令是删除文件和目录的高效工具,但一旦误操作,如执行rm-rf/或rm-rf/*,极易导致系统数据灾难,本文针对不同场景... 目录引言理解 rm 命令及误操作风险rm 命令基础常见误操作案例防护方案使用 rm编程 别名及安全删除

python获取指定名字的程序的文件路径的两种方法

《python获取指定名字的程序的文件路径的两种方法》本文主要介绍了python获取指定名字的程序的文件路径的两种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要... 最近在做项目,需要用到给定一个程序名字就可以自动获取到这个程序在Windows系统下的绝对路径,以下

Linux下MySQL数据库定时备份脚本与Crontab配置教学

《Linux下MySQL数据库定时备份脚本与Crontab配置教学》在生产环境中,数据库是核心资产之一,定期备份数据库可以有效防止意外数据丢失,本文将分享一份MySQL定时备份脚本,并讲解如何通过cr... 目录备份脚本详解脚本功能说明授权与可执行权限使用 Crontab 定时执行编辑 Crontab添加定

SpringBoot 多环境开发实战(从配置、管理与控制)

《SpringBoot多环境开发实战(从配置、管理与控制)》本文详解SpringBoot多环境配置,涵盖单文件YAML、多文件模式、MavenProfile分组及激活策略,通过优先级控制灵活切换环境... 目录一、多环境开发基础(单文件 YAML 版)(一)配置原理与优势(二)实操示例二、多环境开发多文件版

使用docker搭建嵌入式Linux开发环境

《使用docker搭建嵌入式Linux开发环境》本文主要介绍了使用docker搭建嵌入式Linux开发环境,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面... 目录1、前言2、安装docker3、编写容器管理脚本4、创建容器1、前言在日常开发全志、rk等不同

HTTP 与 SpringBoot 参数提交与接收协议方式

《HTTP与SpringBoot参数提交与接收协议方式》HTTP参数提交方式包括URL查询、表单、JSON/XML、路径变量、头部、Cookie、GraphQL、WebSocket和SSE,依据... 目录HTTP 协议支持多种参数提交方式,主要取决于请求方法(Method)和内容类型(Content-Ty

Ubuntu如何升级Python版本

《Ubuntu如何升级Python版本》Ubuntu22.04Docker中,安装Python3.11后,使用update-alternatives设置为默认版本,最后用python3-V验证... 目China编程录问题描述前提环境解决方法总结问题描述Ubuntu22.04系统自带python3.10,想升级

Python 基于http.server模块实现简单http服务的代码举例

《Python基于http.server模块实现简单http服务的代码举例》Pythonhttp.server模块通过继承BaseHTTPRequestHandler处理HTTP请求,使用Threa... 目录测试环境代码实现相关介绍模块简介类及相关函数简介参考链接测试环境win11专业版python