通过socket实现wed服务器
前言:
本文要实现一个可以显示一个基本网站框架的wed服务器,其中涉及到html语言(超文本协议)
因为本文中的socket通讯我已经被我封装到自定义函数中,所以看官要先了解socket通讯哦。
文章最后有源码链接
第一步:通过epoll实现一个简单的服务器
第二步:编写要发送的网站文本(htnl文本)
第三步:实现用socket以http协议发送html文本
第四步:测试结果及对服务器的压力测试
第一步:通过epoll实现一个简单的服务器
思路:
1:创建一个epoll描述符;
2:把你要监听的socket放入其中;
3:创建一个(epoll_event)数组用来存放有事件的socket;
4:启动epoll,创建一个整数使其得到epoll的返回值(即有事件socket的总和)
5:创键一个循环陆续访问有事件的socket
23 int fd = epoll_create(1); //创建epoll描述符
24
25 struct epoll_event ev;
26 ev.data.fd = fwd.sock; //fwd.sock是封装后的服务端监听socket
27 ev.events = EPOLLIN;
28
29 epoll_ctl(fd,EPOLL_CTL_ADD,fwd.sock,&ev); //把监听的sock加入句柄中
30 struct epoll_event epoll_fd[MAX]; //创建一个数组用存储有事件发生的socket
31
32 while(1)
33 {
34 int sum = epoll_wait(fd,epoll_fd,MAX,-1); //epoll等待客户端的连接并返回事件发生的总数
第二步:编写要发送的网站文本(html文本)
这个就是以html格式书写的简易版网站
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <meta charset="UTF-8"> <!--声明使用UTF-8来显示文本-->
5 <title>国际中转站</title> <!--网页显示的标题-->
6 </head>
7 <body>
8 <h1>请选择您的目的地:</h1> <!--网页内的文本-->
9 <form method="post" enctype="multipart/form-data">
10 <fieldset>
11 <legend>超链接中转站</legend>
12 <p><a href="http://www.baidu.com" target="_blank">百度一下吧</a></p> <!--超连接-->
13 <p><a href="http://www.bilibili.com" target="_blank">二次元集结地</a></p>
14 <p><a href="https://blog.csdn.net" target="_blank">博客博客</a></p>
15 <p><a href="https://github.com" target="_blank">git仓库官网</a></p>
16 <p><a href="https://www.douban.com" target="_blank">豆瓣电影</a></p>
17 <p><a href="http://www.baidu.com" target="_blank">百度一下吧</a></p>
18 </fieldset>
19 <!--<input type="file">-->
20 </form>
21 </body>
22 </html>
第三步:实现用socket以http协议发送html文本
思路:
1:以socket通讯的方式向浏览器发送http协议;
2:把html写入.txt的文本文件中,随后创建文件指针,使用文件指针读取文本文件的内容并合并到http协议中,一起发送到浏览器;
55 FILE *fp; char buf[1024]; //创建文件指针和要发送的字符串
56
57 memset(buf,0,sizeof(buf)); //初始化字符串
58 strcat(buf,"HTTP/1.1 200 ok\r\n"); //以下就是http协议格式
59 strcat(buf,"Connection: close\r\n");
60 strcat(buf,"\r\n"); //到此以上是HTTP协议格式
61
62 if((fp = fopen("wed2.txt","r")) == 0) //打开装有html语言的文本文件
63 {
64 printf("文件打开失败\n"); return -1;
65 }
66
67 char buff[102];
68 memset(buff,0,sizeof(buff));
69
70 while(fgets(buff,sizeof(buff),fp)) //读取文本文件中整行的数据
71 {
72 strcat(buf,buff); //每读取一行就合并到http协议中
73 memset(buff,0,sizeof(buff));
74 }
75 fclose(fp); //关闭文件指针
76
77 send(sockfd,&buf,strlen(buf),0); //像浏览器发送数据
78 close(sockfd); //关闭客户端socket
第四步:测试结果及对服务器的压力测试
对服务器的压力测试我使用的是apachebench
ab是apachebench命令的缩写。
ab的安装
安装命令:yum -y install httpd-tools
ab的使用
常用方式:ab -c 500 -n 5000 http://localhost/(你socket通讯所在的端口号)
-n 在测试会话中所执行的请求个数(总数)
-c 一次产生的请求个数(单次请求次数)
Benchmarking localhost (be patient)
Completed 500 requests
Completed 1000 requests
Completed 1500 requests
Completed 2000 requests
Completed 2500 requests
Completed 3000 requests
Completed 3500 requests
Completed 4000 requests
Completed 4500 requests
Completed 5000 requests
Finished 5000 requests
Server Software: nginx/2.4.6 #测试服务器的名字
Server Hostname: localhost #请求的URL主机名
Server Port: 80 #请求端口
Document Path: / #请求路径
Document Length: 203 bytes #HTTP响应数据的正文长度
Concurrency Level: 500 #并发用户数,这是我们设置的参数之一
Time taken for tests: 3.349 seconds #所有这些请求被处理完成所花费的总时间 单位秒
Complete requests: 5000 #总请求数量,这是我们设置的参数之一
Failed requests: 0 #表示失败的请求数量
Write errors: 0
Total transferred: 1910000 bytes #所有请求的响应数据长度总和。包括每个HTTP响应数据的头信息和正文数据的长度
HTML transferred: 1015000 bytes #所有请求的响应数据中正文数据的总和,也就是减去了Total transferred中HTTP响应数据中的头信息的长度
Requests per second: 1493.02 [#/sec] (mean) #吞吐量,计算公式:Complete requests/Time taken for tests 总请求数/处理完成这些请求数所花费的时间
Time per request: 334.892 [ms] (mean) #用户平均请求等待时间,计算公式:Time token for tests/(Complete requests/Concurrency Level)。处理完成所有请求数所花费的时间/(总请求数/并发用户数)
Time per request: 0.670 [ms] (mean, across all concurrent requests) #服务器平均请求等待时间,计算公式:Time taken for tests/Complete requests,正好是吞吐率的倒数。也可以这么统计:Time per request/Concurrency Level
Transfer rate: 556.97 [Kbytes/sec] received。 #表示这些请求在单位时间内从服务器获取的数据长度,计算公式:Total trnasferred/ Time taken for tests,这个统计很好的说明服务器的处理能力达到极限时,其出口宽带的需求量。
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 12 105.9 0 1007
Processing: 17 134 495.2 23 3248
Waiting: 17 134 495.2 23 3248
Total: 17 147 509.3 23 3260
Percentage of the requests served within a certain time (ms)
50% 23 #50%用户请求在23ms内返回
66% 30 #60%用户请求在30ms内返回
75% 36
80% 42
90% 54
95% 1215
98% 1653 #98%用户请求在1653ms内返回
99% 3247
100% 3260 (longest request)
结语:
人生路漫漫,进步如蜗牛。
明确目标,永不停歇。