实现web服务器中的gzip

 web服务器实现压缩数据发送给浏览器

web服务器使用gzip压缩可以提高网站的响应速度,因为数据压缩会消耗一定的cpu及I/O的。但是可以减少通过网络传输的数据量。

从而提高网站的浏览速度
本程序本人自己在ubuntu中编译成功,在ubuntu中经过Firefox中,window 系统IE 8,Firefox、chrome中测试成功。

本程序需要用到zlib压缩类库,没有装将无法成功,本人只提供在ubuntu中的代码及运行方式。希望大家谅解。关于用到的

zlib库中的知识,稍后会出新的博客做解释,关于gzip压缩的头部请看另外一篇博客 gzip头部格式。

源码及makefile下载地址:http://pan.baidu.com/share/link?shareid=167795&uk=2181414688

直接给大家上源代码。下面为源代码。(如有任何问题,希望大家指出来了)

/*
*主要实现功能,对传输的数据使用gzip进行压缩了
*1.实现绑定本机机器的1024端口作为ReageWeb服务提供网页服务的端口。(避免与机器上装有web服务器产生端口冲突)
* 作者:Reage
* blog:http://blog.csdn.net/rentiansheng
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <string.h>
#include <sys/stat.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <zlib.h>

#define OS_CODE 0x03 /*Unix OS_CODE*/
#define DEFAULT_COMPRESSION Z_DEFAULT_COMPRESSION
#define DEFAULT_WINDOWSIZE -15
#define DEFAULT_MEMLEVEL 9
#define DEFAULT_BUFFERSIZE 8096
#define MAX 1024
#define METHOD 20 //获取数据的方式,使用字符串的长度
#define URI 255 //表示URI的最大长度
#define VERSION 15	//HTTP版本好的最大长度
#define TYPE 20     //表示文件的类型的长度

int res_socket;
void app_exit();

static const char gzip_header[10] = {'37', '213', Z_DEFLATED, 0, 0, 0, 0, 0, 0, OS_CODE};

void put_long (unsigned char *string, unsigned long x) {
	string[0] = (x & 0xff);
	string[1] = ((x >> 8) & 0xff) ;
	string[2] = ((x >> 16) & 0xff) ;
	string[3] = ((x >> 24) & 0xff);
}

/*
@description:将数据使用gzip压缩后发给浏览器
@parameter
sockd:套接字
file: 要压缩的内容了
*/
int gzip_buffer (int  sockd, char * msg, int len) {
	z_stream stream;//zlib使用的。
	int ret, flush;
	char in[MAX];//存放输入的数据
	char send[MAX + 18 ];//存放压缩过后的数据
	unsigned have;
	memcpy (send, gzip_header, 10);
	memset (in, 0, len);
	stream.zalloc = Z_NULL;
	stream.zfree = Z_NULL;
	stream.opaque = Z_NULL;
	stream.avail_in = 0;
	stream.next_in = Z_NULL;
	memcpy (in, msg, len);
	//压缩初始化。
	int tmp_result = deflateInit2(&stream,
				Z_DEFAULT_COMPRESSION,//压缩级别
				Z_DEFLATED,//压缩方式
				-MAX_WBITS,
				8,
				Z_DEFAULT_STRATEGY);
	if (Z_OK != tmp_result) {
		printf("deflateInit error: %drn", tmp_result);
		return 0;
	}
	stream.avail_in = len; //要压缩数据的长度
	stream.next_in = in;	//要压缩数据的首地址
	stream.avail_out = MAX;  //可存放的最大输出结果的长多。就是压缩后数据的最大长度
	stream.next_out = send + 10; //存放压缩数据的开始位置,send前十个字节用来放头部
	ret = deflate (&stream,Z_FINISH); //压缩
	assert (ret != Z_STREAM_ERROR);
	switch (ret) {
		case Z_NEED_DICT:
			ret = Z_DATA_ERROR;
		case Z_DATA_ERROR:
		case Z_MEM_ERROR:
			(void)inflateEnd (&stream);
			return ret;
	}
	have = MAX - stream.avail_out;
	unsigned crc = crc32(0L, in, len);
	char * tail = send + 10 + have;
	put_long (tail, crc);
	put_long (tail + 4, len);
	write (sockd, send, have + 18);
	deflateEnd (&stream);
	return 1;
}

/*
@description:开始服务端监听
@parameter
ip:web服务器的地址
port:web服务器的端口
@result:成功返回创建socket套接字标识,错误返回-1

*/
int socket_listen( char *ip, unsigned short int port){
	int res_socket; //返回值
	int res, on;
	struct sockaddr_in address;
	struct in_addr in_ip;
	res = res_socket = socket(AF_INET, SOCK_STREAM, 0);
	setsockopt(res_socket, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
	memset(&address, 0, sizeof(address));
	address.sin_family = AF_INET ;
	address.sin_port =htons(port);
	address.sin_addr.s_addr = htonl(INADDR_ANY); //inet_addr("127.0.0.1");
	res = bind( res_socket, (struct sockaddr *) &address, sizeof( address ) );
	if(res) { printf( "port is used , not to repeat bindn" ); exit(101); };
	res = listen(res_socket,5);
	if(res) { printf( "listen port is error ;n" ); exit( 102 );  };
	return res_socket ;
}

/*
@description:向客户端发送网页头文件的信息
@parameter
conn_socket:套接字描述符。
status:http协议的返回状态码。
@s_status:http协议的状态码的含义
@filetype:向客户端发送的文件类型
*/
void send_http_head(int conn_socket){
	char buf[MAX];
	memset(buf, 0, MAX);
	sprintf(buf, "HTTP/1.0 %d OKrn", 200);
	sprintf(buf, "%sServer: Reage Web Serverrn", buf);
	sprintf(buf, "%sContent-Type: text/htmlrn", buf);
	sprintf(buf, "%sContent-Encoding: gziprnrn", buf);
	write(conn_socket, buf, strlen(buf));
} 

int main(int argc, char * argv[] ){
	int  conn_socket;
	int tmp ;
	int line ;
	struct sockaddr_in client_addr;
	char buf[MAX];
	int len = sizeof(client_addr);
	char method[METHOD], uri[MAX], version[VERSION], type[TYPE];
	char msg[] = "<br><br><h1>Reage Web Server gzip support text!
</h1><br/><h1><a href = "http://blog.csdn.net/rentiansheng">Reage blog</a>";
	res_socket = socket_listen( "127.0.0.1", 1024) ;
	//当按ctrl+c结束程序时调用,使用app_exit函数处理退出过程
	signal(SIGINT, app_exit);
	while(1){
		conn_socket = accept( res_socket, (struct sockaddr * )&client_addr, &len );
		printf("reagen");
		tmp = read (conn_socket, buf, MAX-1);
		buf [MAX - 1] = 0;
		send_http_head(conn_socket);
		gzip_buffer (conn_socket, msg, strlen(msg));
		close(conn_socket);
  	} 

}

void app_exit(){
	//回复ctrl+c组合键的默认行为
	signal (SIGINT, SIG_DFL);
	//关闭服务端链接、释放服务端ip和端口
	close(res_socket);
	printf("n");
	exit(0);
}

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索int
, 数据
, include
, stream
, char
define
java实现web服务器、c语言实现web服务器、linux c实现web服务器、web服务器设计与实现、实现web服务器,以便于您获取更多的相关知识。

时间: 2024-10-25 11:47:21

实现web服务器中的gzip的相关文章

ios-图片没有上传到web服务器中

问题描述 图片没有上传到web服务器中 上传一个图片到web服务器上,但是上传后之后图片的名字被保存了,图片没保存 代码: - (void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info { [self dismissModalViewControllerAnimated:YES]; NSData *image = UIImage

Ajax一定要在web服务器中才能跑起来????

问题描述 请问HMTL能跑xmlhttprequest读取xml的数据吗,是否要再web服务器上跑的?望高手指点原理! 解决方案 解决方案二:多去看看基础知识吧.xmlhttprequest对象是javascript的而且跟服务器没关系.哎呀我也说不明白了你这问题太操蛋...解决方案三:要看浏览器是不是支持用XMLHTTP组件加载本地文件,支持的话,本地也能用,不需要装web服务器.试试看firefox

Nginx服务器中使用gzip压缩的相关配置解析_nginx

gzip压缩使用 gzip 压缩可以降低网站带宽消耗,同时提升访问速度. 主要在nginx服务端将页面进行压缩,然后在浏览器端进行解压和解析, 目前大多数流行的浏览器都迟滞gzip格式的压缩,所以不用担心. 默认情况下,Nginx的gzip压缩是关闭的,同时,Nginx默认只对text/html进行压缩 主要配置如下: gzip on;#开启 gzip_http_version 1.0;#默认1.1 gzip_vary on; gzip_comp_level 6; gzip_proxied an

Tornado Web服务器中处理空白字符的解决方案_服务器其它

Tornado模板引擎一直有一个坑,有时候你可能觉得并不影响正常使用,但强迫症就是受不了:模板会去掉每行前后的空格. 最后出来的页面就是这样: 不缩进真的很影响心情的好吧,特别是对一个python开发者. 国外一些Q&A对这个情况也有一些讨论,其中提到比较多的就是compress_whitespace.在github找到一个issue:https://github.com/tornadoweb/tornado/issues/178,就是在抱怨空白字符的问题.空白字符在<pre>中被去除

如何在 Ubuntu 15.04/CentOS 7 中安装 Lighttpd Web 服务器

Lighttpd 是一款开源 Web 服务器软件.Lighttpd 安全快速,符合行业标准,适配性强并且针对高配置环境进行了优化.相对于其它的 Web 服务器而言,Lighttpd 占用内存更少:因其对 CPU 占用小和对处理速度的优化而在效率和速度方面从众多 Web 服务器中脱颖而出.而 Lighttpd 诸如 FastCGI.CGI.认证.输出压缩.URL 重写等高级功能更是那些面临性能压力的服务器的福音. 以下便是我们在运行 Ubuntu 15.04 或 CentOS 7 Linux 发行

当Web服务器与AD服务器分开时,无法通过Web服务器访问AD中的信息

问题描述 以前是将web服务器与AD服务器都用一台时的时候,通过访问web网站可以正常读取其中的AD信息.但是,当将web服务器与AD服务器分开后,即无法访问通过访问web网站读取AD中的信息.报错信息如下.出现了一个操作错误.说明:执行当前Web请求期间,出现未处理的异常.请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误的出处的详细信息.异常详细信息:System.DirectoryServices.DirectoryServicesCOMException:出现了一个操作错误.源错误:

Linux下Tomcat与Apache Web服务器整合

apache|web|web服务|web服务器 1.引言      基于Web技术的Internet/Intranet近年来已经得到了广泛的应用,Intranet是以TCP/IP协议为基础.以Web为核心的企业内部网,用户通过低成本.简单易用的客户浏览器就能随时随地到企业的Web站点上查阅自己所需的数据.浏览器客户端操作界面的一致性避免了C/S模式客户端程序的多样性,而服务器端的开放和基于标准的连接方案使企业很方便地通过Internet同外界联系:同时,Web信息动态的.交互式的发布方式从根本上

Linux下Tomcat与Apache Web服务器的整合

1.引言基于Web技术的Internet/Intranet近年来已经得到了广泛的应用,Intranet是以TCP/IP协议为基础.以Web为核心的企业内部网,用户通过低成本.简单易用的客户浏览器就能随时随地到企业的Web站点上查阅自己所需的数据.浏览器客户端操作界面的一致性避免了C/S模式客户端程序的多样性,而服务器端的开放和基于标准的连接方案使企业很方便地通过Internet同外界联系:同时,Web信息动态的.交互式的发布方式从根本上改变了企业的服务质量,增加了企业的商业机会.在许多用户看来,

嵌入式设备web服务器比较

目录(?)[-] Boa Thttpd Mini_httpd Shttpd Lighttpd Goahead AppWeb Apache 开发语言和开发工具 结论 备注   现在在嵌入式设备中所使用的web服务器主要有:boa.thttpd.mini_httpd.shttpd.lighttpd.goaheand.appweb和apache等. Boa 1.介绍 Boa诞生于1991年,作者Paul Philips.是开源的,应用很广泛,特别适合于嵌入式设备,网上流行程度很广.它的官方网站说boa