http server v0.1_http_server.c
/****************************************************************
filename: http_server.c
author: xxxx
function: Main file of http server
Impliment the response of Get and Post mehtods history:
created by xxxx date: 2014.01.03 *****************************************************************/ #include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <strings.h>
#include <unistd.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <signal.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h> #include "mime.h"
#include "http_common.h"
#include "http_webapp.h"
// __DEBUG__ is debug tag #define BACK_LOG 50
#define SOCKLEN sizeof(struct sockaddr_in) //
static int open_socket(struct sockaddr_in*);
static int accept_client(int sockfd, struct sockaddr_in* paddr);
static void wait_child(); static void write_response_body(int connfd, char* uri, int filesize);
void process_request(int connfd); int main()
{
// char type[MAX_FILE_TYPE_LEN]="";
// get_mime_type("test.html",type); int sockfd = ;
int connfd = ;
struct sockaddr_in sockaddress;
pid_t chld = ;
//struct sigaction sa; bzero(&sockaddress, sizeof(struct sockaddr_in));
signal(SIGCHLD, wait_child);
//open sock
if((sockfd=open_socket(&sockaddress)) == -)
{
perror("open socket failed");
return -;
} //accept client connection
while()
{
connfd = accept_client(sockfd, &sockaddress); #if __DEBUG__
printf("client accept [%d]\n ", connfd);
#endif if((chld = fork()) > )
{ //root
close(connfd);
continue;
}else if(chld == )
{ //childi
process_request(connfd);
close(sockfd);
exit();
} } return ;
} /*--------------------------------------------------------------- functionname: open_socket
param: NA
return: return sockfd on success, -1 on fail
author: xxxx ----------------------------------------------------------------*/
static int open_socket(struct sockaddr_in* paddr)
{
int sockfd = ;
struct sockaddr_in sockaddress; bzero(&sockaddress, sizeof(sockaddress)); if((sockfd = socket(AF_INET, SOCK_STREAM, )) == -)
return -; sockaddress.sin_family = AF_INET;
sockaddress.sin_port = htons(HTTP_PORT); inet_pton(AF_INET, "10.174.8.163", &(sockaddress.sin_addr)); if(bind(sockfd, (struct sockaddr*)(&sockaddress), sizeof(sockaddress)) == -)
return -; if(listen(sockfd, BACK_LOG) == -)
return -; *paddr = sockaddress;
return sockfd;
} /*--------------------------------------------------------------- functionname: accept_client
param: NA
return: return connfd on success, -1 on fail
author: xxxx ----------------------------------------------------------------*/ static int accept_client(int sockfd, struct sockaddr_in* paddr)
{
socklen_t len = SOCKLEN;
int connfd = ; if(paddr != NULL)
{
connfd = accept(sockfd, (struct sockaddr*)(paddr), &len);
}else
{
connfd = -;
}
return connfd;
} /*---------------------------------------------------------------- functionname: wait_child_exit
param: NA
return: NA
author: xxxx TO KILL CHILD PROCESS, avoid ZOOBIE -----------------------------------------------------------------*/ static void wait_child()
{
int status = ;
while(waitpid(-, &status, WNOHANG) > )
{
#if 0
printf("child process exit\n");
#endif
}
return;
} /*----------------------------------------------------------------- functionname: process_request
param: NA
return: NA
author: xxxx http request process
history:
create by xxxx, 2014.1.08, add simple abilities -----------------------------------------------------------------*/ void process_request(int connfd)
{
char request[MAX_REQUEST_LEN];
STR_REQUEST strreq;
EN_MIME_TYPE type = MIME_ELSE;
EN_REP_STATUS status = HTTP_END;
STR_RESP response;
long filesize = ;
FILE* fstream = NULL; bzero(&strreq, sizeof(STR_REQUEST));
bzero(request, sizeof(request));
bzero(&response, sizeof(STR_RESP)); if(recv(connfd, request, sizeof(request), ) >)
{ if(parse_request(request, &strreq) ==)
{
#if __DEBUG__
printf("request:%s\n", request);
#endif get_mime_type(strreq.URI,&type); // file does not exist 404
if(file_exist(strreq.URI) == -)
{
status = HTTP_NOT_FOUND;
fstream = fopen(HTML_404, "rb");
}else
{
status = HTTP_OK;
fstream = fopen(strreq.URI, "rb");
} filesize=get_file_size(fstream);
#if __DEBUG__
printf("request file size = [%ld]\n", filesize);
#endif
//response.data = (void*)malloc(filesize);
//bzero(response.data, filesize);
get_response_head(status,type,response.head,(int)filesize);
#if __DEBUG__
printf("response head = [%s]", response.head);
#endif
//if(get_response_body(type, response.data, strreq.URI, filesize) == -1)
// perror("fill response body failed"); #if __DEBUG__
//printf("response body = [%s]\n", (char*)(response.data));
#endif
fclose(fstream);
send(connfd, response.head, strlen(response.head), );
write_response_body(connfd, strreq.URI, (int)filesize);
shutdown(connfd, SHUT_RD);
close(connfd);
}
}
} static void write_response_body(int connfd, char* uri, int filesize)
{
int fd =;
void* bodybuf = NULL;
fd = open(uri, O_RDONLY, );
bodybuf = mmap(NULL, filesize, PROT_READ, MAP_PRIVATE, fd, );
send(connfd, bodybuf, filesize, );
munmap(bodybuf, filesize);
}
http server v0.1_http_server.c的更多相关文章
- http server v0.1_http_reponse.c
#include <string.h> #include <sys/stat.h> #include <sys/mman.h> #include <fcntl ...
- http server v0.1_http_parse.c
#include <stdio.h> #include <string.h> #include <stdlib.h> #include "mime.h&q ...
- http server v0.1_http_webapp.c
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h&g ...
- http server v0.1_mime.c
#include <string.h> #include "mime.h" static STR_MIME_MAP mime_map[]= { MIME_MAP(MIM ...
- 用FileZilla Server开FTP
FileZilla(教程)是经典的开源FTP解决方案,包括FileZilla客户端和FileZilla Server.其中,FileZilla Server的功能比起商业软件FTP Serv-U毫不逊 ...
- DNS隧道之DNS2TCP实现——dns2tcpc必须带server IP才可以,此外ssh可以穿过墙的,设置代理上网
我自己的命令: server端: dns2tcpd -F -d 1 -f ./dns2tcpd.conf 输出: 09:08:59 : Debug options.c:97 Add resource ...
- docker 下 安装rancher 笔记
sudo yum update 更新系统环境 curl -sSL https://get.docker.com/ | sh 安装最新docker版本 systemctl start docker.se ...
- 容器基础(七): 使用docker compose部署程序
配置 在上一节的基础上, 增加如下的docker-compose.yml文件, 然后用docker-compose up命令启动容器进行部署: version: " services: s ...
- 容器基础(八): 使用docker swarm部署程序
环境 基于上一节的env/server:v0.1, env/worker:v0.1镜像, 在基于debian8.2的两台机器上测试部署docker swarm. docker service部署 ➜ ...
随机推荐
- ArcGIS Engine中如何获取Map中已经选择的要素呢
1.使用IEnumFeturea对象获取map中的FeatureSelection,该方法可以获取所有图层的选择要素.IMap中的FeatureSelection可不是IFeatureSelectio ...
- Android仿微信UI布局视图(圆角布局的实现)
圆角button.或布局能够在xml文件里实现,但也能够使用图片直接达到所需的效果,曾经版本号的微信就使用了这样的方法. 实现效果图: watermark/2/text/aHR0cDovL2Js ...
- 【转】cocos2d-x学习笔记03:绘制基本图元
第一部分:基本图形绘制 cocos2dx封装了大量opengl函数,用于快速绘制基本图形,这些代码的例子在,tests\DrawPrimitivesTest目录下 注意,该方法是重载node的draw ...
- PHP5常量
用函数 define()设置常量 define函数有3个参数 1.必选,常量的名称,标识符 2.必选,常量的值 3.可选,默认不设置,常量名称大小写敏感.如果设置true,常量名称不区分大小写! 下面 ...
- 复杂对象创建终结者(Builder Pattern)
捣鼓了很长时间,终于对建造者模式有初步理解,现在写篇记录下.缘起就是创建的对象比较复杂,需按功能分散.类似造一辆汽车,作为汽车厂家,你需要造车身,造轮胎等,精髓在于领导者(Director),领导者指 ...
- JavaScript的DOM操作(二)
一:window.history对象 历史记录,通过历史记录可以操作页面前进或者后退 window.history.back();后退 window.history.forward();前进 wind ...
- ado.net 学习小结
连接数据源 Connection对象.Connection对象处于最顶层,是所有数据访问请求的关口.我们通过其暴露的属性进行配置.下面是一段连接字符串的示例. if (string.IsNullOrE ...
- 移动设备日期选择插件(基于JQUERY)
上周花了2个小时写的一个日期选择插件,比较适合移动端的设备.先看个效果图吧.如果刚好是你需要的就往下吧,不需要的也可以继续..... 其实网络上已经有的了类似的成熟插件,比如基于mobiscroll, ...
- Spring3 + Spring MVC+ Mybatis 3+Mysql 项目整合
项目环境背景: 操作系统:win7 JDK:1.7 相关依赖包,截图如下:
- C# - winform使用Dictionary的时候,程序一闪而过!
概述: 具体也不知道是多线程造成,还是Dictionary的缺陷. 解决方案: 1.如果可能会添加相同键值,你就别用add,直接添加键值,这样不报错 2.使用Try...catch可以捕获异常. 3. ...