1 Star 0 Fork 5

陈赛/网络编程示例代码

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
httpd.c 3.53 KB
一键复制 编辑 原始数据 按行查看 历史
LIU Yu 提交于 2021-10-13 22:38 . 增加异常处理
#include <stdio.h>
#include <stdlib.h> //malloc
#include <string.h> //memset
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/ip.h> //sockaddr_in
#include <arpa/inet.h> //inet_ntop
#include <signal.h>
#include <unistd.h> //chroot
//解析请求头,返回请求路径
char* parse_request(char *line)
{
char method[10];
char protocol[10];
char* path = NULL;
puts(line);
//%ms会自动分配内存
sscanf(line, "%9s %ms %9s", method, &path, protocol);
printf("method = %s\n", method);
printf("path = %s\n", path);
printf("protocol = %s\n", protocol);
return path;
}
int main()
{
signal(SIGPIPE, SIG_IGN);
int listenfd = socket(AF_INET, SOCK_STREAM, 0);
if (listenfd < 0)
{
perror("socket");
return 1;
}
int opt = 1;
setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
struct sockaddr_in saddr;
memset(&saddr, 0, sizeof(saddr));
saddr.sin_family = AF_INET;
saddr.sin_addr.s_addr = htonl(INADDR_ANY);
saddr.sin_port = htons(80);
if (bind(listenfd, (struct sockaddr *)&saddr, sizeof(saddr)) < 0)
{
perror("bind");
return 1;
}
if (listen(listenfd, 64) < 0)
{
perror("listen");
return 1;
}
chroot(".");
puts("web server start");
while (1)
{
struct sockaddr_in caddr;
socklen_t addrlen = sizeof(caddr);
int connfd;
connfd = accept(listenfd, (struct sockaddr *)&caddr, &addrlen);
char ipstr[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &caddr.sin_addr, ipstr, sizeof ipstr);
printf("client %s connected\n", ipstr);
if (connfd < 0)
{
perror("accept");
continue;
}
FILE* sfp = fdopen(connfd, "r+");
if (!sfp)
{
perror("fdopen");
continue;
}
char buf[BUFSIZ];
fgets(buf, BUFSIZ, sfp);
char* path = parse_request(buf);
puts(path);
//读到空行结束
while(fgets(buf, BUFSIZ, sfp) && strlen(buf) > 2)
{
printf(buf);
}
FILE* fp = fopen(path, "r+");
if (!fp)
{
//文件不存在,返回404
perror("fopen");
fprintf(sfp, "HTTP/1.1 404 Page Not Found\r\n");
fprintf(sfp, "Content-Type: text/html\r\n");
fprintf(sfp, "Content-Length: 36\r\n");
fprintf(sfp, "\r\n");
fprintf(sfp, "<html><body><p>Nothing</p></body></html>");
}
else
{
//获取文件大小(标准IO)
fseek(fp, 0, SEEK_END);
long file_size = ftell(fp);
fseek(fp, 0, SEEK_SET);
printf("file size: %ld\n", file_size);
//分配内存并读取文件到内存
char* file_buf = (char*)malloc(file_size);
if (!file_buf)
{
perror("malloc");
return 1;
}
fread(file_buf, 1, file_size, fp);
//发送响应消息
fprintf(sfp, "HTTP/1.1 200 OK\r\n");
fprintf(sfp, "Content-Type: text/plain\r\n");
fprintf(sfp, "Content-Length: %ld\r\n", file_size);
fprintf(sfp, "\r\n");
fwrite(file_buf, 1, file_size, sfp);
free(file_buf);
fclose(fp);
}
free(path);
fclose(sfp);
}
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
C
1
https://gitee.com/alasai/network-programming-example.git
[email protected]:alasai/network-programming-example.git
alasai
network-programming-example
网络编程示例代码
master

搜索帮助