-
Notifications
You must be signed in to change notification settings - Fork 0
/
MyTinyHttpd.cpp
160 lines (136 loc) · 4.02 KB
/
MyTinyHttpd.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<string.h>
#include<pthread.h>
#include<unistd.h>//close()
//html部分使用的Tinyhttpd,有空更改
int sock_init(){
int sockfd;
struct sockaddr_in server_addr;
server_addr.sin_family=AF_INET;
server_addr.sin_port=htons(4000);
server_addr.sin_addr.s_addr=inet_addr("0.0.0.0");//本机全部ip 或者使用htonl(INADDR_ANY) 不要把‘.’写成‘,’
if((sockfd=socket(PF_INET,SOCK_STREAM,0))<0)
perror("socket error"),exit(0);
if(bind(sockfd,(struct sockaddr*)&server_addr,sizeof(server_addr))<0)
perror("bind error"),exit(0);
if(listen(sockfd,5)<0)
perror("listen error"),exit(0);
printf("http server is running on port %d\n",ntohs(server_addr.sin_port));
return sockfd;
}
void not_found(int connectfd){
char buf[1024];
sprintf(buf, "HTTP/1.1 404 NOT FOUND\r\n");
send(connectfd, buf, strlen(buf), 0);
sprintf(buf, "Content-Type: text/html\r\n");
send(connectfd, buf, strlen(buf), 0);
sprintf(buf, "\r\n");
send(connectfd, buf, strlen(buf), 0);
sprintf(buf, "<HTML><TITLE>Not Found</TITLE>\r\n");
send(connectfd, buf, strlen(buf), 0);
sprintf(buf, "<BODY><P>The server could not fulfill\r\n");
send(connectfd, buf, strlen(buf), 0);
sprintf(buf, "your request because the resource specified\r\n");
send(connectfd, buf, strlen(buf), 0);
sprintf(buf, "is unavailable or nonexistent.\r\n");
send(connectfd, buf, strlen(buf), 0);
sprintf(buf, "</BODY></HTML>\r\n");
send(connectfd, buf, strlen(buf), 0);
}
void method_head(int connectfd){
char buf[1024];
sprintf(buf, "HTTP/1.1 200 OK\r\n");
send(connectfd, buf, strlen(buf), 0);
sprintf(buf, "Content-Type: text/html\r\n");
send(connectfd, buf, strlen(buf), 0);
sprintf(buf, "\r\n");
send(connectfd, buf, strlen(buf), 0);
}
void method_get(char* url,int connectfd){
if(url[strlen(url)-1]=='/')
strcpy(url,"index.html");
printf("请求文件:%s\n",url);
FILE* file_point=fopen(url,"r");
if(file_point==NULL)
not_found(connectfd);
else{
char buf[1024];
method_head(connectfd);
fgets(buf,1024,file_point);
while(!feof(file_point)){
send(connectfd,buf,strlen(buf),0);//一定要使用strlen,不要使用sizeof,不然乱码
fgets(buf,1024,file_point);
}
fclose(file_point);
}
}
void method_not_create(int connectfd){
char buf[1024];
sprintf(buf, "HTTP/1.1 501 Method Not Create\r\n");
send(connectfd, buf, strlen(buf), 0);
sprintf(buf, "Content-Type: text/html\r\n");
send(connectfd, buf, strlen(buf), 0);
sprintf(buf, "\r\n");
send(connectfd, buf, strlen(buf), 0);
sprintf(buf, "<HTML><HEAD><TITLE>Method Not Create\r\n");
send(connectfd, buf, strlen(buf), 0);
sprintf(buf, "</TITLE></HEAD>\r\n");
send(connectfd, buf, strlen(buf), 0);
sprintf(buf, "<BODY><P>HTTP request method not supported.\r\n");
send(connectfd, buf, strlen(buf), 0);
sprintf(buf, "</BODY></HTML>\r\n");
send(connectfd, buf, strlen(buf), 0);
}
void* request(void* arg){
int connectfd=*(int*)arg;
char buf[2048];
char method[255];
char url[255];
if(recv(connectfd,buf,2048,0)<0)
perror("recv error"),exit(0);
int i=0;//标记buf读取位置
while(buf[i]!=' '){
method[i]=buf[i];
i++;
}
while(buf[i]==' ')i++;//忽略空格
int j=0;
while(buf[i]!=' '){
url[j]=buf[i];
i++;
j++;
}
if(strcmp(method,"GET")==0){
printf("method:GET\n");
method_get(url,connectfd);
}
else if(strcmp(method,"HEAD")==0){
printf("method:HEAD\n");
method_head(connectfd);
}
else{
printf("method not create\n");
method_not_create(connectfd);
}
close(connectfd);
}
int main(){
int sockfd=sock_init();
int connectfd;
struct sockaddr_in client;
pthread_t pthread_id;
socklen_t client_size=sizeof(client);//必须如此使用,不然accept不阻塞
while(1){
if((connectfd=accept(sockfd,(struct sockaddr*)&client,&client_size))<0)
perror("accept error"),exit(0);
printf("NEW LINK\n");
if(pthread_create(&pthread_id,0,request,(void*)&connectfd)<0)
perror("pthread_create error"),exit(0);
}
return 0;
}