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

相关文章

Go语言中nil判断的注意事项(最新推荐)

《Go语言中nil判断的注意事项(最新推荐)》本文给大家介绍Go语言中nil判断的注意事项,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录1.接口变量的特殊行为2.nil的合法类型3.nil值的实用行为4.自定义类型与nil5.反射判断nil6.函数返回的

Linux中SSH服务配置的全面指南

《Linux中SSH服务配置的全面指南》作为网络安全工程师,SSH(SecureShell)服务的安全配置是我们日常工作中不可忽视的重要环节,本文将从基础配置到高级安全加固,全面解析SSH服务的各项参... 目录概述基础配置详解端口与监听设置主机密钥配置认证机制强化禁用密码认证禁止root直接登录实现双因素

Go语言数据库编程GORM 的基本使用详解

《Go语言数据库编程GORM的基本使用详解》GORM是Go语言流行的ORM框架,封装database/sql,支持自动迁移、关联、事务等,提供CRUD、条件查询、钩子函数、日志等功能,简化数据库操作... 目录一、安装与初始化1. 安装 GORM 及数据库驱动2. 建立数据库连接二、定义模型结构体三、自动迁

SQLite3 在嵌入式C环境中存储音频/视频文件的最优方案

《SQLite3在嵌入式C环境中存储音频/视频文件的最优方案》本文探讨了SQLite3在嵌入式C环境中存储音视频文件的优化方案,推荐采用文件路径存储结合元数据管理,兼顾效率与资源限制,小文件可使用B... 目录SQLite3 在嵌入式C环境中存储音频/视频文件的专业方案一、存储策略选择1. 直接存储 vs

在Linux终端中统计非二进制文件行数的实现方法

《在Linux终端中统计非二进制文件行数的实现方法》在Linux系统中,有时需要统计非二进制文件(如CSV、TXT文件)的行数,而不希望手动打开文件进行查看,例如,在处理大型日志文件、数据文件时,了解... 目录在linux终端中统计非二进制文件的行数技术背景实现步骤1. 使用wc命令2. 使用grep命令

springboot如何通过http动态操作xxl-job任务

《springboot如何通过http动态操作xxl-job任务》:本文主要介绍springboot如何通过http动态操作xxl-job任务的问题,具有很好的参考价值,希望对大家有所帮助,如有错... 目录springboot通过http动态操作xxl-job任务一、maven依赖二、配置文件三、xxl-

Linux如何快速检查服务器的硬件配置和性能指标

《Linux如何快速检查服务器的硬件配置和性能指标》在运维和开发工作中,我们经常需要快速检查Linux服务器的硬件配置和性能指标,本文将以CentOS为例,介绍如何通过命令行快速获取这些关键信息,... 目录引言一、查询CPU核心数编程(几C?)1. 使用 nproc(最简单)2. 使用 lscpu(详细信

Go语言代码格式化的技巧分享

《Go语言代码格式化的技巧分享》在Go语言的开发过程中,代码格式化是一个看似细微却至关重要的环节,良好的代码格式化不仅能提升代码的可读性,还能促进团队协作,减少因代码风格差异引发的问题,Go在代码格式... 目录一、Go 语言代码格式化的重要性二、Go 语言代码格式化工具:gofmt 与 go fmt(一)

linux重启命令有哪些? 7个实用的Linux系统重启命令汇总

《linux重启命令有哪些?7个实用的Linux系统重启命令汇总》Linux系统提供了多种重启命令,常用的包括shutdown-r、reboot、init6等,不同命令适用于不同场景,本文将详细... 在管理和维护 linux 服务器时,完成系统更新、故障排查或日常维护后,重启系统往往是必不可少的步骤。本文

基于Linux的ffmpeg python的关键帧抽取

《基于Linux的ffmpegpython的关键帧抽取》本文主要介绍了基于Linux的ffmpegpython的关键帧抽取,实现以按帧或时间间隔抽取关键帧,文中通过示例代码介绍的非常详细,对大家的学... 目录1.FFmpeg的环境配置1) 创建一个虚拟环境envjavascript2) ffmpeg-py