用c寫的一個簡單web伺服器實現 轉載來自sdlcwangsong
阿新 • • 發佈:2021-01-07
本程式的目的是實現一個web伺服器,在伺服器啟動時讀取配置檔案config.txt,然後瀏覽器向伺服器傳送請求,伺服器向瀏覽器傳送index.html,檔案傳送完畢後伺服器關閉與瀏覽器的連結,告知瀏覽器檔案已傳送完畢,瀏覽器收到index.html檔案後發現還有一個圖片,於是再次傳送請求,伺服器接收到請求後又傳送圖片資訊,傳送完畢後關閉連線。之後,瀏覽器就顯示了完整的網頁了。
下面是實現的程式(寫的很粗糙)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define MAXLINE 80
int main(void)
{
struct sockaddr_in servaddr,cliaddr;
socklen_t cliaddr_len;
int listenfd,connfd;
int p,length=0;
char *ip;
char *port=NULL;
FILE *fp_config;
char str[INET_ADDRSTRLEN];
int i,n;
char title[15];
int fd_index,fd_jpg,ret;
fp_config=fopen("config.txt","r"); if(fp_config<0){ printf("open file error!\n"); return 1; } getline(&port,&length,fp_config); for(i=0;i<strlen(port);i++){ if(port[i]=='\n') port[i]='\0'; } p=atoi(port); listenfd=socket(AF_INET,SOCK_STREAM,0); int opt=1; setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt)); bzero(&servaddr,sizeof(servaddr)); servaddr.sin_family=AF_INET; servaddr.sin_addr.s_addr=htonl(INADDR_ANY); servaddr.sin_port=htons(p); bind(listenfd,(struct sockaddr *)&servaddr,sizeof(servaddr)); listen(listenfd,20); printf("Accepting connections ...\n"); while(1){ cliaddr_len=sizeof(cliaddr); connfd=accept(listenfd,(struct sockaddr *)&cliaddr,&cliaddr_len); while(1){ n=read(connfd,buf,MAXLINE); if(n==0){ printf("the other side has been closed.\n"); break; } i=0; while(buf[i]!='\r'){ title[i]=buf[i]; i++; } title[i]='\0'; if(0==(strcmp(title,"GET / HTTP/1.1"))){ bzero(buf,MAXLINE); strcpy(buf,"HTTP/1.1 200 OK\r\n"); write(connfd,buf,strlen(buf)); bzero(buf,MAXLINE); strcpy(buf,"Content-Type: text/html\r\n"); write(connfd,buf,strlen(buf)); bzero(buf,MAXLINE); buf[0]='\r'; buf[1]='\n'; write(connfd,buf,2); fd_index=open("index.html",O_RDONLY); if(fd_index<0){ printf("open file error!\n"); return fd_index; } bzero(buf,MAXLINE); while((ret=read(fd_index,buf,MAXLINE))>0){ write(connfd,buf,ret); printf("send index data...\n"); bzero(buf,MAXLINE); } close(fd_index); close(connfd); connfd=accept(listenfd,(struct sockaddr *)&cliaddr,&cliaddr_len); bzero(buf,MAXLINE); n=read(connfd,buf,MAXLINE); i=0; while(buf[i]!='\r'){ title[i]=buf[i]; i++; } title[i]='\0'; if(0==(strcmp(title,"GET /mypic.jpg HTTP/1.1"))){ bzero(buf,MAXLINE); strcpy(buf,"HTTP/1.1 200 OK\r\n"); write(connfd,buf,strlen(buf)); bzero(buf,MAXLINE); strcpy(buf,"Content-Type: image/jpg\r\n"); write(connfd,buf,strlen(buf)); bzero(buf,MAXLINE); buf[0]='\r'; buf[1]='\n'; write(connfd,buf,2); fd_jpg=open("mypic.jpg",O_RDONLY); if(fd_jpg<0){ printf("open file error!\n"); return fd_jpg; } bzero(buf,MAXLINE); while((ret=read(fd_jpg,buf,MAXLINE))>0){ write(connfd,buf,ret); printf("send index data...\n"); bzero(buf,MAXLINE); } close(fd_jpg); close(connfd); connfd=accept(listenfd,(struct sockaddr *)&cliaddr,&cliaddr_len); } } } }
}
在當前路徑下有以下檔案
首先開啟伺服器,
然後在瀏覽器中輸入本機IP地址127.0.0.1,瀏覽器顯示完整網頁