Linux 简单的web服务器
最近写了一个简单的web服务器程序,鉴于时间短,代码有很多不妥的地方,不条理,也有些漏洞。只实现了图片、文字的基本功能,也没有对可执行文件代码的实现。记录下来,单纯为以后做个参考。高手勿喷。
同一目录下文件如上:
index.html源码如下:
<html>
<head><title>Test Page</title></head>
<body>
<p>seven</p>
<img src='mypic.jpg'>
</body>
</html>
myhttp.conf为配置文件:
PORT:8000
DIRECTORY:/home/li/my_study/UNIX_GAOJI/myhttp
mypic.jpg是一张图片
server.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <arpa/inet.h>
#define MAXLINE 80
int mycp(int fd_src,int fd_des);
void text_picture(char *buf,char *ask_dir);
int main(void)
{
struct sockaddr_in servaddr,cliaddr;
FILE *fp;
int fd,listenfd,connfd;
long port;
char dir[50],q[50],buf[MAXLINE],ask_dir[50];
char str[INET_ADDRSTRLEN];
char *right1="HTTP/1.1 200 OK\r\n";
char *right2="Content-Type:text/html\r\n";
char *fault1="HTTP/1.1 404 Not Found\r\n";
char *fault2="Content-Type:text/html\r\n";
char *right3="Content-Type: image/jpg\r\n";
char *p=NULL;
int opt=1,n;
socklen_t cliaddr_len;
pid_t pid;
listenfd=socket(AF_INET,SOCK_STREAM,0);
setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));
fp=fopen("myhttp.conf","r");
if(fp==NULL){
printf("fopen error\n");
return -1;
}
fscanf(fp,"PORT:%ld\nDIRECTORY:%s\n",&port,dir);
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family=AF_INET;
servaddr.sin_addr.s_addr=htonl(INADDR_ANY);
servaddr.sin_port=htons(port);
bind(listenfd,(struct sockaddr *)&servaddr,
sizeof(servaddr));
listen(listenfd,20);
printf("Accepting connections ...\n");
while(1){
strcpy(q,dir);
cliaddr_len=sizeof(cliaddr);
connfd=accept(listenfd,(struct sockaddr *)&cliaddr,&cliaddr_len);
read(connfd,buf,MAXLINE);
printf("received from %s at PORT %d\n",
inet_ntop(AF_INET,&cliaddr.sin_addr,str,
sizeof(str)),
ntohs(cliaddr.sin_port));
text_picture(buf,ask_dir);
if((strcmp(ask_dir,"/"))==0){
strcat(ask_dir,"index.html");
strcat(q,ask_dir);
fd=open(q,O_RDONLY);
if(fd<0){
write(connfd,fault1,strlen(fault1));
write(connfd,fault2,strlen(fault2));
}
else{
write(connfd,right1,strlen(right1));
write(connfd,right2,strlen(right2));
write(connfd,"\r\n",2);
mycp(fd,connfd);
close(fd);
}
bzero(ask_dir,50);
bzero(q,50);
close(connfd);
}
if((strcmp(ask_dir,"/mypic.jpg"))==0){
strcat(q,ask_dir);
fd=open(q,O_RDONLY);
if(fd<0){
write(connfd,fault1,strlen(fault1));
write(connfd,fault2,strlen(fault2));
}
else{
write(connfd,right1,strlen(right1));
write(connfd,right3,strlen(right3));
write(connfd,"\r\n",2);
mycp(fd,connfd);
close(fd);
}
bzero(ask_dir,50);
bzero(q,50);
close(connfd);
}
}
return 0;
}
int mycp(int fd_src,int fd_des)
{
int sret,dret;
char str[128];
char *p;
bzero(str,128);
while((sret=read(fd_src,str,128))>0){
p=str;
while(sret){
dret=write(fd_des,p,sret);
sret=sret-dret;
p=p+dret;
}
bzero(str,128);
}
return 0;
}
void text_picture(char *buf,char *ask_dir)
{
int i=4;
int j=0;
for(i=4;buf[i]!=' ';i++){
ask_dir[j]=buf[i];
j++;
}
ask_dir[j]='\0';
}