#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/epoll.h>
void http_parse_request_cmd(char *buf, char *file_name, char *suffix);
char*http_get_type_by_suffix(const char*suffix);
int fsize(FILE *fp);
struct doc_type{
char*suffix;
char*type;};
struct doc_type file_type[]=
{
{"html","text/html"},
{"ico","image-xicon"},
{NULL,NULL}};
char*http_res_hdr_tmpl="HTTP/1.1 200 OK\nServer: bianchengbang\n"
"Accept-Ranges: bytes\nContent-Length: %d\nConnection: closed\n"
"Content-Type: %s\n\n";
int main(){
int serv_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
struct sockaddr_in serv_addr;
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = inet_addr("192.168.137.128");
serv_addr.sin_port = htons(1234);
int isbind=bind(serv_sock, (struct sockaddr*)&serv_addr,sizeof(serv_addr));
if (listen(serv_sock, 20) == -1) {
printf("listen errno\n");
close(serv_sock);
return 0;
}
int epfd=epoll_create(50);
struct epoll_event event;
struct epoll_event* ep_events=malloc(sizeof(struct epoll_event) * 50);
event.events = EPOLLIN;
event.data.fd = serv_sock;
epoll_ctl(epfd, EPOLL_CTL_ADD, serv_sock, &event);
while(1){
int event_cnt = epoll_wait(epfd, ep_events, 50, -1);
if (event_cnt == -1) {
printf("epoll_wait() errno\n");
break;
}
for (int i = 0; i < event_cnt; i++) {
if (ep_events[i].data.fd == serv_sock) {
struct sockaddr_in clnt_addr;
socklen_t adr_sz=sizeof(clnt_addr);
int clnt_sock = accept(serv_sock, (struct sockaddr*)&clnt_addr, &adr_sz);
event.events = EPOLLIN;
event.data.fd = clnt_sock;
epoll_ctl(epfd, EPOLL_CTL_ADD, clnt_sock, &event);
}
else{
char buf[300]={0};
memset(buf, 0, 300);
int num=read(ep_events[i].data.fd, buf, 100);
if(num>0){
char file_name[100]={0};
memset(file_name, 0, 100);
char suffix[100]={0};
memset(suffix, 0, 100);
http_parse_request_cmd(buf, file_name, suffix);
FILE *fp;
if((fp = fopen(file_name, "rb"))==NULL){
printf("服务器不存在%s文件",file_name);
fp=fopen("errno.html", "rb");
memset(suffix, 0, 100);
strcpy(suffix, "html");
}
else{
printf("服务器存在%s文件,发送中...",file_name);
}
int n=fsize(fp);
char*type=http_get_type_by_suffix(suffix);
memset(buf, 0, 300);
sprintf(buf,http_res_hdr_tmpl,n,type);
write(ep_events[i].data.fd,buf,300);
memset(buf, 0, 300);
fread(buf, 1,100,fp);
write(ep_events[i].data.fd,buf,100);
shutdown(ep_events[i].data.fd,SHUT_WR);
fclose(fp);
}
else{
epoll_ctl(epfd, EPOLL_CTL_DEL, ep_events[i].data.fd, NULL);
close(ep_events[i].data.fd);}
}
}
}
close(serv_sock);
close(epfd);
return 0;
}
int fsize(FILE *fp){
int n;
fpos_t fpos;
fgetpos(fp, &fpos);
fseek(fp, 0, SEEK_END);
n = ftell(fp);
fsetpos(fp,&fpos);
return n;
}
void http_parse_request_cmd(char *buf, char *file_name, char *suffix)
{
int file_length = 0, suffix_length = 0;
char *begin = NULL, *end = NULL, *bias = NULL;
begin = strchr(buf, ' ');
begin += 1;
end = strchr(begin, ' ');
*end = 0;
file_length = end - begin - 1;
memcpy(file_name, begin + 1, file_length);
file_name[file_length] = 0;
bias = strrchr(begin, '/');
suffix_length = end - bias;
if (*bias == '/')
{
bias++;
suffix_length--;
}
if (suffix_length > 0)
{
begin = strchr(file_name, '.');
if (begin)
strcpy(suffix, begin + 1);
}
}
char*http_get_type_by_suffix(const char*suffix)
{int i;
for(i=0;file_type[i].suffix;i++){
if(!strcmp(file_type[i].suffix,suffix))
return file_type[i].type;
}
return NULL;
}
用printf调试也输出不了,浏览器访问文件,终端就出现Segmentation fault (core dumped)