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;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/34902.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

spark中pyspark :add

一、RDD的介绍&#xff08;了解&#xff09; RDD:resilient distributed dataset(弹性分布式数据集合 ) spark的计算核心&#xff0c;spark采用rdd管理数据 RDD RDD是spark的一种数据模型&#xff08;规定数据的存储结构和计算方法&#xff09; python中的数据模型 list [] 可…

【linux基础awk】如何基于强大的awk打印列、计算

打印列 awk {print $1} test.txt#-F参数去指定分隔的字符 awk -F "," {print $1,$2} file 匹配打印列 awk /a/ {print $4 "\t" $3} test.txt筛选数值 仅打印那些含有多于18个字符的行。awk length($0) > 18 test.txt 统计数目 #统计行数 less num…

高考填报志愿,找准自己的真兴趣来选择专业

又是一年一度的高考填报志愿的时间了&#xff0c;毕业生们要根据自己的分数&#xff0c;在很短的时间内确定自己的专业。专业千万条&#xff0c;兴趣第一条。专业的选择很大程度上决定着大学的学习生活是否顺利&#xff0c;甚至决定着以后的职业生涯。在纷繁复杂的专业中&#…

Python深度学习技术

原文链接&#xff1a;Python深度学习技术 近年来&#xff0c;伴随着以卷积神经网络&#xff08;CNN&#xff09;为代表的深度学习的快速发展&#xff0c;人工智能迈入了第三次发展浪潮&#xff0c;AI技术在各个领域中的应用越来越广泛。Transformer模型&#xff08;BERT、GPT-…

写一个坏越的个人天地(三)

昨天卡巴卡巴还是投出了学习代码以来的第一份简历,遇到好的岗位还是想争取下的吧,虽然我觉得大概率还是gg了。 昨天完成了首页的上半部分 下半部分我的构思是左右栏,左侧为菜单栏,右侧为业务栏,左侧调整右侧router进行切换内容 可以用来展示js css的小demo 稍微调整下ro…

Vue3 国际化i18n

国际化i18n方案 1. 什么是i18n2. i18n安装、配置及使用2.1 安装2.2 配置2.3 挂载到实例2.4 组件中使用2.5 语言切换 1. 什么是i18n i18n 是“国际化”的简称。在资讯领域&#xff0c;国际化(i18n)指让产品&#xff08;出版物&#xff0c;软件&#xff0c;硬件等&#xff09;无…

[UE虚幻引擎] DTSpeechVoice 文字转语音播放 插件说明

本插件可以在UE中使用蓝图把文本转成语音播放&#xff0c;播放的声音引擎是使用Windows自带的语音引擎&#xff0c;支持Win10&#xff0c;Win11。 系统设置 首先确认电脑是否有语音系统&#xff0c;一般正常安装的电脑都是自带的。 如果要播放多语言的&#xff0c;请自己下载其…

Python光束三维二维标量场和算法

&#x1f3af;要点 &#x1f3af;矢量计算和绘图&#xff1a;&#x1f58a;二维&#xff0c;三维 | &#x1f58a;转换矢量图 | &#x1f58a;矢量和矩阵计算 | &#x1f58a;矢量空间变换和计算 | &#x1f58a;解矢量线性方程 | &#x1f3af;数学和物理矢量计算&#xff1a…

无中心化崛起:Web3对传统互联网的冲击与重构

随着Web3技术的兴起&#xff0c;传统互联网面临着前所未有的挑战和重构。本文将深入探讨Web3的无中心化特性如何对传统互联网产生冲击&#xff0c;以及其可能带来的重大影响和未来发展趋势。 1. 传统互联网的局限与问题 传统互联网&#xff0c;通常称为Web2&#xff0c;主要依…

kafka--发布-订阅消息系统

1. Kafka概述 1. kafka是什么 kafka是分布式的、高并发的、基于发布/订阅模式的消息队列软件系统。 kafka中的重要组件 Producer&#xff1a;消息生产者&#xff0c;发布消息到Kafka集群的终端或服务Consume&#xff1a;消费者&#xff0c;从Kafka集群中消费消息的终端或服…

Python hash编码(go hash编码)

id="中国人" 首先,go语言hash: import (mmh3 "murmurhash3") mmh3.Murmurhash3([]byte(id)) 对应到Python hash编码,可以直接使用mmh3 import mmh3 mmh3.hash(id,signed=False) 其源码可以表示为 def sum32WithSeed(datas, seed=0):c1_32 = 0xcc9e…

《mnist_model.h5》在flask中加载mnist模型

一、在tensorflow中新建及保存模型 启动Jupyter Notebook 新建Notebook 代码 from flask import Flask, request, jsonify # type: ignore import numpy as np # type: ignore import tensorflow as tf # type: ignore import json from PIL import Image # type: i…

Rust编写测试及控制执行

编写测试及控制执行 在 Rust 中&#xff0c;测试是通过函数的方式实现的&#xff0c;它可以用于验证被测试代码的正确性。测试函数往往依次执行以下三种行为&#xff1a; 设置所需的数据或状态运行想要测试的代码判断( assert )返回的结果是否符合预期 让我们来看看该如何使…

sd-wan跨境访问|公司海外工厂加速访问ERP系统解决方案

随着全球化的深入发展和国际市场竞争的加剧&#xff0c;越来越多的企业选择在国外建立工厂&#xff0c;以扩大市场份额和优化资源配置。然而&#xff0c;这也带来了一系列新的挑战&#xff0c;其中之一就是国外工厂员工在访问国内ERP系统时面临的超高延迟等问题。这一问题不仅严…

CJson源码解析之创建不同类型的键值对

文章目录 前言cJSON_CreateNullcJSON_CreateTruecJSON_CreateFalsecJSON_CreateBoolcJSON_CreateNumbercJSON_CreateStringcJSON_strdup函数cJSON_Delete函数 总结 前言 在现代编程中&#xff0c;JSON已经成为了一种非常流行的数据交换格式。它的简洁性和易读性使得开发者可以…

scikit-learn如何处理缺失数据?

scikit-learn处理缺失数据&#xff1a;方法与实践 在数据分析和机器学习项目中&#xff0c;处理缺失数据是一项常见且关键的任务。scikit-learn&#xff08;简称sklearn&#xff09;&#xff0c;作为Python中广泛使用的机器学习库&#xff0c;提供了多种工具和技术来帮助我们处…

ros创建deb功能包安装文件

1、在功能包下执行&#xff1a; bloom-generate rosdebian --os-name ubuntu --ros-distro noetic2、执行&#xff1a; fakeroot debian/rules binary 生成的文件在上级目录。

Linux_应用篇(27) CMake 入门与进阶

在前面章节内容中&#xff0c;我们编写了很多示例程序&#xff0c;但这些示例程序都只有一个.c 源文件&#xff0c;非常简单。 所以&#xff0c;编译这些示例代码其实都非常简单&#xff0c;直接使用 GCC 编译器编译即可&#xff0c;连 Makefile 都不需要。但是&#xff0c;在实…

神经网路学习7-线性模型

一个最简单的线性模型&#xff0c;w是权重&#xff0c;一般来说会取随机值&#xff0c;然后不断学习直到与预期相同 如此以此取每个值与真实值的差值&#xff0c;即评估误差 即找一个合适的权重w&#xff0c;使得平均误差最小 上面的是针对单个样本的&#xff0c;后面的是对…

malloc、free和new delete的区别

malloc/free 和 new/delete 是在 C 中分配和释放内存的两种不同方法。它们主要有以下区别&#xff1a; 1. 语法和用法 malloc 和 free: malloc开辟空间时需要手动计算分配的空间大小 int* p (int*)malloc(sizeof(int) * 10); // 分配10个int类型的内存 // 使用内存 free(p); …