//main.h
//====================================================================================
// The information contained herein is the exclusive property of
// Sunnnorth Technology Co. And shall not be distributed, reproduced,
// or disclosed in whole in part without prior written permission.
// (C) COPYRIGHT 2003 SUNNORTH TECHNOLOGY CO.
// ALL RIGHTS RESERVED
// The entire notice above must be reproduced on all authorized copies.
//====================================================================================
#ifndef _MAIN_H_
#define _MAIN_H_
#include stdio.h>
#include stdlib.h>
#include unistd.h>
#include string.h>
#define RECV_SZIE 1024
#define SEND_SIZE 1024
int cut_list(char *bak[], char *buf, char *str);
void deal_with(int connfd, char *buf);
#endif
//main.h
//=============================================================
// 语法格式: int main(int argc, char *argv[])
// 实现功能: 主函数,建立一个webServer
// 入口参数: argc, argv
// 出口参数: 0
//=============================================================
#include "main.h"
#include sys/socket.h>
#include netinet/in.h>
#include arpa/inet.h>
#include sys/types.h>
int main(int argc, char *argv[])
{
char recvbuf[RECV_SZIE];
int sockfd;
struct sockaddr_in servAddr;
unsigned short port = 80;
pid_t pid;
if(argc > 1)
{
port = atoi(argv[1]);
}
printf("webserver Started at port %d\n", port);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd 0)
{
perror("Invalid socket!");
exit(1);
}
bzero(&servAddr, sizeof(servAddr)); //initialize server
servAddr.sin_family = AF_INET;
servAddr.sin_port = htons(port);
servAddr.sin_addr.s_addr = htonl(INADDR_ANY);
printf("Binding server to port %d\n", port);
if(bind(sockfd, (struct sockaddr *)&servAddr, sizeof(struct sockaddr)) != 0)
{
close(sockfd);
perror("binding err!");
exit(1);
}
if(listen(sockfd, 1) != 0)
{
close(sockfd);
perror("listen err!");
exit(1);
}
char cliIP[INET_ADDRSTRLEN];
size_t recvLen;
struct sockaddr_in cliAddr;
size_t cliAddrLen = sizeof(cliAddr);
while(1)
{
int connfd = accept(sockfd, (struct sockaddr *)&cliAddr, &cliAddrLen);
if(connfd 0)
{
close(sockfd);
perror("accept err!");
exit(1);
}
inet_ntop(AF_INET, &cliAddr.sin_addr.s_addr, cliIP, INET_ADDRSTRLEN);
printf("client ip = %s\n", cliIP);
if((pid = fork()) 0)
{
perror("fork err!");
exit(1);
}
else if(pid == 0)
{
close(sockfd);
if((recvLen = read(connfd, recvbuf, RECV_SZIE)) > 0)
{
printf("%s\n", recvbuf);
deal_with(connfd, recvbuf);
memset(recvbuf, 0, RECV_SZIE);
}
close(connfd);
exit(1);
}
else
{
close(connfd);
printf("client closed!\n");
}
}
close(sockfd);
return 0;
}
//webserver.c
//=============================================================
// 语法格式: void deal_with(int connfd, char *buf)
// 实现功能: 处理客户端的请求
// 入口参数: conndf,buf
// 出口参数: 无
//=============================================================
#include "main.h"
#include fcntl.h>
#include sys/stat.h>
void deal_with(int connfd, char *buf)
{
char *resp_head = "HTTP/1.1 200 OK\r\n" \
"Content-Type: text/html\r\n" \
"Content-Length:%ld\r\n" \
"\r\n";
char *not_found = "HTTP/1.1 404 Not Found\r\n" \
"Content-Type: text/html\r\n" \
"Content-Length: 40\r\n" \
"\r\n" \
"File not found";
char *bad_request = "HTTP/1.1 400 Bad Request\r\n" \
"Content-Type: text/html\r\n" \
"Content-Length: 39\r\n" \
"\r\n" \
"Bad Request (Invalid Hostname)";
/* char *moved_permanently =
"HTTP/1.1 301 Moved Permanently\r\n"\
"Content-Length: 147\r\n" \
"Content-Type: text/html\r\n" \
"Location: %s\r\n" \
"\r\n" \
"Document MovedObject MovedThis document may be found here";
*/
char tmp_buf[SEND_SIZE] = {""};
char *tmp_bak[10];
char *first_line[5];
int fd;
FILE *fp;
struct stat file_buf;
int file_len = 0;
fp = fdopen(connfd, "w+"); //
cut_list(tmp_bak, buf, "\r\n");
cut_list(first_line, tmp_bak[0], " ");
if((first_line[0] != NULL) && (strcmp(first_line[0], "GET") == 0))
{
if(first_line[1] != NULL)
{
if(strcmp(first_line[1], "/") == 0)
{
strcat(first_line[1], "bai.htm");
}
first_line[1] = ++first_line[1];
if((fd = open(first_line[1], O_RDONLY)) == -1)
{
write(connfd, not_found, strlen(not_found));
perror("open index.html err!");
return ;
}
stat(first_line[1], &file_buf);
file_len = file_buf.st_size;
fprintf(fp, resp_head, file_len);
fflush(fp);
int len;
while((len = read(fd, tmp_buf, SEND_SIZE)) > 0)
{
write(connfd, tmp_buf, len);
memset(tmp_buf, 0, SEND_SIZE);
}
close(fd);
}
else
{
write(connfd, bad_request, strlen(bad_request));
}
}
return ;
}
/*************************************************************
*自己封装的字符串切割函数
*功 能:切割字符串
*************************************************************/
int cut_list(char *bak[], char *buf, char *str)
{
int i = 0;
int size = 0;
bak
= strtok(buf, str);
while((bak[++i] = strtok(NULL, str)));
size = i;
return size;
}
注:以上内容整理自网络