Linux下以C构建WEB服务并响应XHR(XMLHttpRequest)请求

本文介绍了一种不依赖CGI,而是利用C语言在Linux环境下构建WEB服务,以响应XMLHttpRequest(XHR)的GET和POST请求。通过分析请求类型和HTTP头,服务端接收并处理POST的FormData数据。文中提供了简单的实现步骤,并展示了XHR请求的GET和POST两种方式的效果。源码可在CSDN下载,欢迎交流指正。
摘要由CSDN通过智能技术生成

网页要与硬件打交道,通常的方式是使用CGI,那除了CGI之外,还有没有其他的方式呢?我们知道XHR是可以在不提交表单的情况下,实现与WEB服务端的交互的,那么服务端除了CGI来作出响应外,还有没有其他的方法呢?

答案是有的,我们先来看效果图。

1.XHR的POST请求效果图



2.XHR的GET请求效果图



因为WEB的交互在本质上就是HTTP请求,既然是HTTP请求,那么我们只要以HTTP的形式作出回应,那不就可以了吗?

再思考一个问题,XHR请求有两种方式,一种是GET,一种是POST。这和表单的提交方式是相似的。如果有注意观察,就会发现,提交表单时采用GET请求时,表单数据会跟在URL后面,以问号作为开始,并以KEY-VALUE对的形式以&符号分隔多个KEY-VALUE对。而采用POST方法时,则不是这样的。

那POST的数据又是如何提交出去的?服务端收到的数据又会是什么 样的呢?为此,我以C构建了一个简单的WEB服务来响应XHR的POST请求。下面是实现的步骤。

1.在服务端以SOCKET的形式监听服务端口。

/* server.c */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>

#define MAXLINE 1024
#define FILE_NAME_LEN_MAX 256
#define DEFEULT_SERVER_PORT 8000
#define RESPONSE_HEADER_LENGTH_MAX 1024
#define BOUNDARY_LEN_MAX 256
#define KEY_LEN_MAX 256
#define VALUE_LEN_MAX 1024
#define BACK_LEN_MAX 10240
#define FORM_DATA_LEN_MAX 10240

struct FormData
{
  char Key[KEY_LEN_MAX];
  char Value[VALUE_LEN_MAX];
  struct FormData *Next;
};
char * fetchMethod(const char * buf);
int hasFormDataInUrl(const char * buf,int bufLen);
char * fetchFileName(const char * buf,int bufLen); 
char * readFileBytes(const char * fileName);
char * fetchBoundary(const char * buf,int bufLen);
void handleFormData(int connfd,const char * buf,const char * boundary,const int isFormDataInUrl/*0:not.1:is*/);
struct FormData * fetchFormData(const char * buf,const char *boundary);
struct FormData * fetchFormDataInUrl(const char * buf);
void responseFormData(int connfd,struct FormData * head,const char *method);
void response(int connfd,char *responseContent,int responseContentLength,char *responseCode,char *contentType);

int main(int argc, char *argv[])
{
	struct sockaddr_in servaddr, cliaddr;
	socklen_t cliaddr_len;
	int listenfd, connfd;
	char buf[MAXLINE];
	char *data;
        char *responseContent;
	char str[INET_ADDRSTRLEN];
	char *method;
	char *fileName;
	char *boundary;
	int i,n;
	int port= DEFEULT_SERVER_PORT;

	if(argc>1)
	  {
	    port=atoi(argv[1]);//Input port
	  }
	if(port<=0||port>0xFFFF)
	  {
	    printf("Port(%d) is out of range(1-%d)\n",port,0xFFFF);
	    return;
	  }
	listenfd = socket(AF_INET, SOCK_STREAM, 0);

	bzero(&servaddr, sizeof(servaddr));
	servaddr.sin_family = AF_INET;
	servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
	servaddr.sin_port = htons(port);
    
	bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));

	listen(listenfd, 20);

	printf("Listen %d\nAccepting connections ...\n",port);
	while (1)
	  {
		cliaddr_len = sizeof(cliaddr);
		connfd = accept(listenfd, 
				(struct sockaddr *)&cliaddr, &cliaddr_len);
	  
		n = read(connfd, buf, MAXLINE);
		printf("---------------------\n");
		printf("received from %s at PORT %d\n",
		       inet_ntop(AF_INET, &cliaddr.sin_addr, str, sizeof(str)),
		       ntohs(cliaddr.sin_port));
		printf("read:%d\n%s\n",n,buf);	
			
		method=fetchMethod(buf
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值