实现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压缩后发给浏览器@parametersockd:套接字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:开始服务端监听@parameterip: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:向客户端发送网页头文件的信息@parameterconn_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);}

(0)

相关推荐

  • 电脑Web服务器中网站的基本身体验证怎么开启

    大家在使用电脑是时候肯定会遇到很多问题,今天小编跟大家分享的是电脑Web服务器中网站的基本身体验证怎么开启.希望可以帮助到大家.具体如下:1. 首先我们打开电脑左下方的"开始"按钮 ...

  • 电脑Web服务器中的windows身份验证功能怎么开启

    我们在使用电脑的时候肯定会遇到很多问题.今天小编跟大家分享的是电脑Web服务器中的windows身份验证功能怎么开启.具体如下:1. 首先我们打开电脑,之后点击左下方的开始选项.2.在弹出的窗口中点击 ...

  • 【在web服务器中查找黑客的蛛丝马迹】

    操作方法 01 现在服务器之类的东西大家很怕病毒的侵害或者是黑客的攻击,一旦被攻击了损失惨重,因此想要看看你的服务器有没有被黑客攻击可以追踪下黑客的蛛丝马迹,怎么追踪呢,下面告诉你. 现今的网络,安全 ...

  • 让Web服务器不再拒认ASP网页

    受ASP动态网页的吸引,笔者决定用Dreamweaver做一个ASP格式的学校主页.然而,当笔者将Web服务器中Htm格式的网页换成新做的ASP网页时却发现:新做的这些ASP网页在校园网内的所有计算机 ...

  • 怎样在Win7系统中搭建Web服务器?

    打开控制面板,选择并进入"程序",双击"打开或关闭Windows服务",在弹出的窗口中选择"Internet信息服务"下面所有地选项,点击确 ...

  • 如何关闭Windows server 2008系统电脑中的Web服务器远程连接?

    相信很多小伙伴都有在使用Windows server 2008 R2系统的电脑,其中的Web服务器远程连接如何才能关闭呢?方法很简单,下面小编就来为大家介绍.具体如下:1. 首先,启动电脑,打开桌面左 ...

  • 虚拟机中怎么配置web服务器

    想要配置好微博服务器,先要添加一个角色"web服务器",这里主要说的是虚拟机中怎么配置web服务器 操作方法 01 现在打开虚拟机,并开机,如下图所示: 02 打开"开始 ...

  • 如何从外网访问虚拟机中web服务器

    本文章适用于虚拟机内部浏览器可以访问自己架设的web服务器,可是从主机访问虚拟机的web页面就不行了.前提是主机先连路由器 操作方法 01 设置虚拟机的网络适配器为桥接模式 02 在主机里.单击 开始 ...

  • linux搭建nginx WEB服务器的教程

    下文来为各位介绍一篇在linux搭建nginx WEB服务器的教程,如果各位不想使用apache环境了,想用nginx环境就可以和小编一起来看看。 1、下载nginx 命令:wget http://n ...