您的位置:首页 > 其它

WebSever简易实现

2015-08-16 12:44 288 查看


//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;

}

注:以上内容整理自网络
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: