文件1: webServer.h
1 //#pragma once
2 #ifndef _WEB_SERVER_H_
3 #define _WEB_SERVER_H_
4
5 #include <time.h>
6
7 #define MAX_SIZE 1000
8
9 typedef struct
10 {
11 int fd;
12 time_t timeout; //使用超时时刻的时间戳表示
13 }ConnTimeout; //超时的一个节点元素
14
15 typedef struct
16 {
17 ConnTimeout* elems; //顺序表的基地址
18 int length; //顺序表的长度
19 int size; //顺序表的空间
20 }TimeoutSqList;
21
22 //顺序表的接口
23 //初始化
24 bool initList(TimeoutSqList& L);
25 //添加
26 bool listAppend(TimeoutSqList& L, ConnTimeout e);
27 //删除
28 bool listDelete(TimeoutSqList& L, int i);
29 //销毁
30 void destroyList(TimeoutSqList& L);
31 //遍历
32 void listPrint(TimeoutSqList& L);
33
34 #endif // !_WEB_SERVER_H_
文件2: SqList.cpp
1 #include <iostream>
2 #include "webServer.h"
3
4 using namespace std;
5
6 //初始化
7 bool initList(TimeoutSqList& L) //构造一个空的顺序表L
8 {
9 L.elems = new ConnTimeout[MAX_SIZE];
10 if (!L.elems)
11 {
12 return false;
13 }
14 L.length = 0;
15 L.size = MAX_SIZE;
16 return true;
17
18 }
19
20 //添加
21 bool listAppend(TimeoutSqList& L, ConnTimeout e)
22 {
23 if (L.length == L.size) return false; //存储空间已满
24 L.elems[L.length] = e;
25 L.length++; //表长增1
26 return true;
27 }
28
29 //删除
30 bool listDelete(TimeoutSqList& L, int i)
31 {
32 if (i < 0 || i >= L.length) return false; //不合法
33 if (i == L.length - 1) //删除最后一个元素,直接删除
34 {
35 L.length--;
36 return true;
37 }
38 for (int j = i; j < L.length - 1; j++)
39 {
40 L.elems[j] = L.elems[j + 1]; //被删除元素之后的元素前移
41 }
42 L.length--;
43 return true;
44 }
45
46 //销毁
47 void destroyList(TimeoutSqList& L)
48 {
49 if (L.elems) delete[]L.elems;//释放存储空间
50 L.length = 0;
51 L.size = 0;
52 }
53
54 //遍历
55 void listPrint(TimeoutSqList& L)
56 {
57 cout << "当前: " << L.size << ", 已保存元素个数length: " << L.length << endl;
58 for (int j = 0; j <= L.length - 1; j++)
59 {
60 cout << "fd: " << L.elems[j].fd << ", timeout: " << L.elems[j].timeout << endl;
61 }
62 cout << endl;
63 }
文件3: webServer.cpp
1 #include <iostream>
2 #include <time.h>
3 #include <Windows.h>
4 #include "webServer.h"
5
6 using namespace std;
7
8 static void checkTimeouts(TimeoutSqList& list, time_t now);
9
10 int main()
11 {
12 time_t now, end;
13 time_t last_timeout; //
14 TimeoutSqList list;
15
16
17 time(&now); //获取当前时间戳
18 end = now + 60;
19 last_timeout = now;
20
21 initList(list);
22
23 for (int i = 0; i < 10; i++)
24 {
25 ConnTimeout e;
26 e.fd = i;
27 e.timeout = now + 5 + 2 * i;
28 listAppend(list, e);
29 }
30
31 listPrint(list);
32
33 do
34 {
35 if (last_timeout + 0.999 < now)
36 {
37 checkTimeouts(list, now); //检查超时的链接
38 last_timeout = now;
39 }
40 Sleep(10);
41 time(&now);
42
43 } while (now < end);
44
45 }
46
47 void checkTimeouts(TimeoutSqList& list, time_t now)
48 {
49 int fd, i;
50 cout << "检查超时fd......\n";
51
52 for (int i = 0; i < list.length; i++)
53 {
54 if (list.elems[i].timeout > now)
55 {
56 continue;
57 }
58
59 //超时,清理链接
60 fd = list.elems[i].fd;
61 //关闭链接
62 printf("关闭链接[fd = %d] 已经超时,关闭链接! \n", fd);
63
64 //删除顺序表中的元素
65 listDelete(list, i);
66 //循环完了后会i++, 删除元素时注意元素下标,不i--会删错
67 i--;
68 }
69 }