代码如下
http_server.cpp
/*
* compile: g++ -o http_server.out http_server.cpp -lpthread
* run: ./http_server.out
* before you run this programe ,you should have a file named "index.html" in your root directory
*/
#include <sys/socket.h>
#include <sys/types.h>
#include <poll.h>
#include <unistd.h>
#include <netdb.h>
#include <error.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>
#define HTTP_SERVRE_PORT 80 //http server port
#define BUFFSIZE 1024 // integer 1 stands for ture : running
#define LISTENQ 10
void http_response( int new_fd, char *request )
{
char *token = strtok( request, " " ); //token is the name of the method
char *uri = strtok( NULL, " " ); //the file you want to get
char file[64];
sprintf( file, ".%s", uri );
{
FILE *fp = fopen( file, "rb" );
if( fp == 0 )
{
char response[] = "HTTP/1.1 404 NOT FOUND\r\n\r\n";
write(new_fd,response,strlen(response));
}
else
{
int file_size ;
char *content;
char response[1024];
fseek( fp, 0, SEEK_END );//to the end of the file
file_size = ftell( fp ); //get file size
fseek( fp, 0, SEEK_SET );//to the beginning of the file
content = (char*)malloc( file_size + 1 );
fread( content, file_size, 1, fp );
content[file_size] = 0;
sprintf( response, "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nContent-Length: %d\r\n\r\n%s", file_size, content );
write(new_fd,response,strlen(response));
free( content );
}
}
}
int sockfd;
struct sockaddr_in server_addr;
struct sockaddr_in client_addr;
//init param of the http server
bool initialize_server()
{
//socket
if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)
{
fprintf(stderr,"Socket error:%s\n\a",strerror(errno));
exit(1);
}
bzero(&server_addr,sizeof(struct sockaddr_in));
server_addr.sin_family=AF_INET;
server_addr.sin_addr.s_addr=htonl(INADDR_ANY);
server_addr.sin_port=htons(HTTP_SERVRE_PORT);
//bind
if(bind(sockfd,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr))== -1)
{
fprintf(stderr,"Bind error:%s\n\a",strerror(errno));
exit(1);
}
//listen
if(listen(sockfd,LISTENQ)==-1)
{
fprintf(stderr,"Listen error:%s\n\a",strerror(errno));
exit(1);
}
}
//connection thread
void * connection_thread(void * arg)
{
pthread_detach(pthread_self());//回制定线程结束时回收资源
int new_fd = *(int *)arg;
int nbytes;
char request[BUFFSIZE];
if((nbytes=read(new_fd,request,BUFFSIZE))==-1)
{
fprintf(stderr,"Read Error:%s\n",strerror(errno));
exit(1);
}
request[nbytes]='\0';
printf("new_fd: %d\n",new_fd);
printf("Request From Client (%s:%d):\ncontent of char * request[] is :\n%s\n",inet_ntoa(client_addr.sin_addr),client_addr.sin_port,request);
http_response(new_fd, request );
close(new_fd);
pthread_exit(0);
}
//main thread
void httpserver_start_work()
{
unsigned int sin_size;
while(1)
{
//accept
int new_fd;
sin_size=sizeof(struct sockaddr_in);
if((new_fd=accept(sockfd,(struct sockaddr *)(&client_addr),&sin_size))==-1)
{
fprintf(stderr,"Accept error:%s\n\a",strerror(errno));
exit(1);
}
//recv
pthread_t tid;
//create a new thread to serve each request
pthread_create(&tid, NULL, connection_thread, &new_fd);
}
close(sockfd);
}
int main()
{
//init param of the http server
initialize_server();
//main thread
httpserver_start_work();
return 0;
}
type http://your-hostname/index.html in your web browser the click enter
you will see this;