简单的Web服务器模型

本文介绍了一个简易Web服务器的实现过程,使用C语言编程并通过socket编程实现了HTTP请求的接收与响应。该服务器能够解析HTTP GET请求并返回指定文件的内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/**
* 程序是用来作为Web服务器的,用于的作为客户请求,这提供服务的程序
* 由于服务器不需要可视话的界面,仅仅是提供一个后台的进程来响应客户的请求
* 我们知道的Web协议有HTTP,所有要实现web服务,就要知道HTTP协议的表现形似以及
* 响应的方式,客户端请求的格式是:Get filename,下面是具体的实现code
*/
#include<sys/socket.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<netinet/in.h>
#include<netdb.h>
#include<stdlib.h>
#include<pthread.h>
#include<errno.h>
#include<stdio.h>

#define SOCKET_ERROR -1

/**
*下面的函数声明是用来进行客户端的请求解析的
*/
const char *openGET(const char *,int);

/**
*下面是主函数,用于服务的主函数
*/
int main(int argc,const char *argv[]){
	int sockfd,newfd;
	struct sockaddr_in hostaddr;
	struct sockaddr_in clientaddr;
	int clientlen=sizeof(struct sockaddr);
	
	sockfd=socket(AF_INET,SOCK_STREAM,0);
	if(sockfd==SOCKET_ERROR){
		perror("socket faile");
		exit(0);
	}

	hostaddr.sin_family=AF_INET;
	hostaddr.sin_port=htons(80);
	hostaddr.sin_addr.s_addr=htonl(INADDR_ANY);
	bzero(&hostaddr.sin_zero,0);
	
	int ret=bind(sockfd,(struct sockaddr *)&hostaddr,sizeof(struct sockaddr));
	if(ret==SOCKET_ERROR){
		perror("socket faile");
		close(sockfd);
		exit(0);
	}
	int lisret=listen(sockfd,5);
	if(lisret==SOCKET_ERROR){
		perror("socket faile");
		close(sockfd);
		exit(0);
	}

	while(1){
		printf("wait requestion........\n");
		newfd=accept(sockfd,(struct sockaddr *)&clientaddr,&clientlen);
		if(newfd==SOCKET_ERROR){
			perror("accept fail");
			close(sockfd);
			exit(0);
		}
		printf("have request to.....\n");
		char buf[100];
		memset(buf,0,20);
		int recvlen=recv(newfd,buf,100,0);
		/**
		*上面的代码已经获得了HTTP的请求了,并且已经得到客户端的请求
		*下面的就是用于响应客户端的请求,也就是把客户端的请求响应给
		*客户,那么就是传送文件或者是响应程序的运行结果
		*下面就是对从客户端获得的请求进行解析以及响应
		*/
		const char *p=openGET(buf,100);
		/**
		*下面开始响应客户的请求,也就是读取文件并传送给客户
		*由客户的浏览器进行显示,打开就是客户请求的文件
		*/
		int fd;
		fd=open(p,O_RDONLY);
		if(!fd){
		 printf("open file fail\n");
		}
		char readbuf[100];
		memset(buf,0,512);
		ssize_t reret=0;
		printf("begin read data!\n");
		/**
		*下面是简单的打开用户请求的文件,并将其传送给请求的客户
		*/
		while((reret=read(fd,readbuf,100))>0){
			printf("%s\n",readbuf);
			send(newfd,readbuf,reret,0);
		}
		
		printf("errno:%s\n",strerror(errno));
		printf("readbuf:%s  len:%d\n",readbuf,reret);
		/**
		*当响应了客户的请求以后就可以关闭相应的文件描述符了,因为
		*这样可以使响应速度更快,并且也不会占用资源
		*/
		close(fd);
		close(newfd);
		
	}
	printf("create socket success\n");
	
	return 0;
}

const char *openGET(const char *recv,int len){
	char *buf=(char *)(recv+5);
	static char data[100];
	memset(data,0,100);
	int i=0;
	for(i=0; i<len; ++i){
		if(buf[i]==' ')
			break;
		data[i]=buf[i];
	}
	return data;
}












评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值