1 Star 0 Fork 0

minzui/anolis_os_first_assignment

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
webserver.c 3.57 KB
一键复制 编辑 原始数据 按行查看 历史
minzui 提交于 2022-03-07 23:24 . first commit
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <pthread.h>
#define BUF_SIZE 1024
void* request_handler(void* arg);// 用于处理请求,发送dmidecode的数据
void error_handler(char* message);// 处理错误
int main(int argc, int *argv[]) {
// 返回一个AF_INET(ip4),SOCK_STREAM(字节流套接字),IPPROTO_TCP(TCP传输协议)的socket描述符
// 这是一个监听套接字描述符
int server_sock = socket(AF_INET, SOCK_STREAM, 0);
if(server_sock == -1) {
error_handler("no more socket!!!");
exit(-1);
}
struct sockaddr_in server_addr;
memset(&server_addr, 0, sizeof(server_addr));// 这句话是干嘛的?
server_addr.sin_family = AF_INET;// 设置协议族为ipv4
server_addr.sin_port = htons(3527);// 设置监听端口,将host unigned short字节序转换为 net 字节序
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);// 监听任意网卡的报文数据,0.0.0.0表示来自任意网卡的包都要发给server
// 绑定监听端口与套接字, 不过bind后面两个参数不太明确
if(bind(server_sock,(struct sockaddr*)&server_addr, sizeof(server_addr)) == -1) {
error_handler("bind() error");
exit(-1);
}
// 监听
if(listen(server_sock, 20) == -1) {
error_handler("listen() error");
exit(-1);
}
// 并发处理http request
pthread_t t_id;
while(1) {
// accept返回真正与client交互的socket描述符
struct sockaddr_in client_addr;
int client_addr_len = sizeof(client_addr); // accept的第三个参数需要地址😓
int client_sock = accept(server_sock, (struct sockaddr*)&client_addr,&(client_addr_len));
if(client_sock == -1) {
error_handler("accept() error");
exit(-1);
}
if(pthread_create(&t_id, NULL, request_handler, &client_sock) == -1) {
error_handler("pthread error");
exit(-1);
}
pthread_detach(t_id);// 主线程与子线程分离,两者相互不干涉,子线程结束同时子线程的资源自动回收。
}
exit(0);
}
void *request_handler(void *arg) {
int client_sock = *((int*)arg);
int p[2];
pipe(p);
char status[] = "HTTP/1.1 200 OK\n\n";
char header[] = "Content-Type: text/html;charset=utf-8\n\n";
char body[BUF_SIZE];
// write(client_sock, status, sizeof(status));
// write(client_sock, header, sizeof(header));
// cout<<sizeof(status)<<" "<<sizeof(header)<<endl;
printf("%lu %lu\n", sizeof(status), sizeof(header));
write(client_sock, "HTTP/1.1 200 OK\n\n", 15);// 为什么这里的长度明明是18,但是要设置成15
write(client_sock, "Content-Type: text/html; charset=UTF-8\n\n", 40);
// write(client_sock, "hello", 6);// 为什么body中有值,就是下载鸭???
// write(client_sock, body, sizeof(body));
if(fork() == 0) {
close(p[0]);
close(STDOUT_FILENO); // 将子进程标准输出重定向到管道end of write
dup(p[1]);// dup用来复制参数oldfd所指的文件描述符。当复制成功时,返回最小的尚未被使用过的文件描述符
execlp("dmidecode", "dmidecode", NULL);
}
close(p[1]);// 关闭父进程end of write
int len;
while((len = read(p[0],body, BUF_SIZE)) != 0) {
write(client_sock, body, len);
}
shutdown(client_sock, SHUT_RDWR);
}
void error_handler(char *message) {
fputs(message, stderr);
fputs("\n", stderr);
exit(1);
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/minzui/anolis_os_first_assignment.git
git@gitee.com:minzui/anolis_os_first_assignment.git
minzui
anolis_os_first_assignment
anolis_os_first_assignment
master

搜索帮助