├── README.md ├── picture ├── map类管理.png ├── scheduler.png ├── 代码统计.png ├── 全局图.png ├── 目录2.0.png ├── 目录3.0.png └── 目录管理类.png └── src ├── Hash ├── hash.h ├── md5.cpp ├── md5.h └── test.cpp ├── HttpControl ├── head.h ├── http_control.cpp ├── http_control.h ├── main.cpp └── myallocator.h ├── NginxPool ├── Nginx.cpp ├── Nginx.h └── NginxPoolTypeInfo.h ├── cli ├── client │ └── cli.cpp ├── include │ ├── LinuxFun.h │ └── STL.h ├── main.cpp └── sockpair │ ├── sockpair.cpp │ └── sockpair.h ├── jsoncpp ├── cppjson.h └── json.cc ├── scheduler ├── ThreadPool │ ├── Condition.cpp │ ├── Condition.h │ ├── Makefile │ ├── Mutex.cpp │ ├── Mutex.h │ ├── Thread.cpp │ ├── Thread.h │ ├── Threadpool.cpp │ ├── Threadpool.h │ ├── c.sh │ ├── head.h │ ├── main │ └── main.cpp └── dispatch │ ├── dispatch.cpp │ └── dispatch.h └── ser ├── include ├── LinuxFun.h └── STL.h ├── main.cpp └── process ├── Dir.h ├── FTP.h └── process.cpp /README.md: -------------------------------------------------------------------------------- 1 | # filetransfer 2 | ## 文件传输 3 | ### 项目概览 4 | - 使用 event loop per thread + thread pool 线程池构建调度器框架 5 | - 使用半同步半异步进程池构建框架 6 | - 使用STL容器实现用户表格的管理 7 | - 使用一致性哈希策略进行负载的均衡 8 | - 使用Nginx内存池完成HTTP请求的内存的管理 9 | 10 | ### 项目工具 11 | - Linux centos7 , vim , gcc, g++, gdb , git 12 | 13 | ### 项目时间 14 | 2018/4/2 -- 2018/5/4 15 | 16 | ### 项目展望 17 | - 目前已经完成基本功能,后期准备加入 mysql, redis以及使用 libevent 编写 socket 18 | - 成型之后会做成一个 HTTP 文件服务器,会加入中间层 dispatch负载均衡器 19 | - 负载均衡器的负载策略由 Hash 文件中的一致性哈希实现 20 | 21 | ## 目录结构: 22 | 23 | ![](https://i.imgur.com/C9XcCXS.png) 24 | ## 代码统计 25 | ![](https://i.imgur.com/GAHk3Ky.png) 26 | 27 | ## 由于最近在加负载均衡的处理,所以代码有很多没有push更新 28 | 29 | ## 主要职责 30 | - LinuxFun.h 项目中使用的Linux头文件 31 | - http_control.cpp HTTP 请求的处理 32 | - STL.h 项目中使用的C++ STL的头文件 33 | - cli.cpp 客户端的逻辑代码 34 | - ser.cpp 服务端的逻辑代码 35 | - sockpair.cpp 封装了sockpair创建双工管道的过程 36 | - Dir.h 目录流处理的代码 37 | - process.cpp worker事件处理代码 38 | - FTP.h 处理连接的代码使用半同步半异步进程池 39 | - hash.h 一致性哈希的主代码 40 | - md5.h md5的主代码 41 | - md5.cpp md5的实现 42 | - scheduler 调度器的实现 43 | - jsoncpp json解析代码 44 | # 主要逻辑图 45 | 用于管理文件与MD5的map表 46 | 47 | ![](https://i.imgur.com/EIaQLOj.png) 48 | # 用于管理目录的map表 49 | 50 | ![](https://i.imgur.com/GFX1lsD.png) 51 | # 线程池框架图 52 | ![](https://i.imgur.com/xfIKuSq.png) 53 | 54 | # 设计最终目标 55 | 56 | ![](https://i.imgur.com/WNcWxx9.png) 57 | 58 | -------------------------------------------------------------------------------- /picture/map类管理.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Darkfaker/filetransfer/8ba2bced677b43f0608aabbbfedbf12298bf5da5/picture/map类管理.png -------------------------------------------------------------------------------- /picture/scheduler.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Darkfaker/filetransfer/8ba2bced677b43f0608aabbbfedbf12298bf5da5/picture/scheduler.png -------------------------------------------------------------------------------- /picture/代码统计.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Darkfaker/filetransfer/8ba2bced677b43f0608aabbbfedbf12298bf5da5/picture/代码统计.png -------------------------------------------------------------------------------- /picture/全局图.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Darkfaker/filetransfer/8ba2bced677b43f0608aabbbfedbf12298bf5da5/picture/全局图.png -------------------------------------------------------------------------------- /picture/目录2.0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Darkfaker/filetransfer/8ba2bced677b43f0608aabbbfedbf12298bf5da5/picture/目录2.0.png -------------------------------------------------------------------------------- /picture/目录3.0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Darkfaker/filetransfer/8ba2bced677b43f0608aabbbfedbf12298bf5da5/picture/目录3.0.png -------------------------------------------------------------------------------- /picture/目录管理类.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Darkfaker/filetransfer/8ba2bced677b43f0608aabbbfedbf12298bf5da5/picture/目录管理类.png -------------------------------------------------------------------------------- /src/Hash/hash.h: -------------------------------------------------------------------------------- 1 | 2 | /******************************/ 3 | #define _CRT_SECURE_NO_WARNINGS 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include "md5.h" 14 | using namespace std; 15 | /******************************/ 16 | class Md5{ 17 | public: 18 | string get_Md5(const string &str){ 19 | return MD5(str).toStr(); 20 | } 21 | }; 22 | 23 | template 24 | class CNode{ 25 | public: 26 | typedef vector _Vec_Type; 27 | typedef T _Val_Type; 28 | private: 29 | string _real_key; 30 | T _real_msg; 31 | public: 32 | _Vec_Type _Vir_Node; 33 | CNode(string key, const T& msg); 34 | CNode(){} 35 | string Get_real_key(); 36 | T Get_real_msg(); 37 | }; 38 | 39 | template 40 | class CNodeCtl{ 41 | public: 42 | typedef string (*MakeConnect)(const T&, int); 43 | typedef vector _Vec_Type; 44 | typedef unordered_map> _Map_Type; 45 | typedef T _Val_Type; 46 | _Map_Type _Node_map; 47 | public: 48 | /* make a HOOK function */ 49 | static MakeConnect MakeMsg; 50 | //static function MakeMsg; 51 | static void Set_Fun(MakeConnect cfunc); 52 | /* add node */ 53 | string Add_Node(const T &msg); 54 | string Add_Vir_Node(string key, const int N); 55 | /* del node */ 56 | vector Del_Node(const T &msg); 57 | T Get_Msg(const string &key); 58 | }; 59 | template 60 | typename CNodeCtl::MakeConnect CNodeCtl::MakeMsg = NULL; 61 | 62 | template 63 | class CHash{ 64 | public: 65 | typedef unordered_map _Map_Type; 66 | typedef T _Val_Type; 67 | private: 68 | /* static map */ 69 | _Map_Type _Ip_map; 70 | /* real node -> vir node*/ 71 | CNodeCtl _One_Node; 72 | /* init number */ 73 | int _Init_count; 74 | public: 75 | /* static instance */ 76 | void Add_ser(const T &msg); 77 | 78 | void Del_ser(const T &msg); 79 | 80 | T Find_ser(const T &msg); 81 | 82 | void Show_ser(); 83 | 84 | CHash(int n, const vector &vec); 85 | }; 86 | 87 | //CNode code 88 | /********************************************/ 89 | template 90 | inline CNode::CNode(string key, const T &msg) 91 | :_real_key(key), _real_msg(msg){} 92 | 93 | template 94 | inline string CNode::Get_real_key(){ 95 | return _real_key; 96 | } 97 | 98 | template 99 | inline T CNode::Get_real_msg(){ 100 | return _real_msg; 101 | } 102 | /********************************************/ 103 | 104 | //CNodeCtl code 105 | /********************************************/ 106 | template 107 | inline void CNodeCtl::Set_Fun(MakeConnect cfunc){ 108 | if (NULL == cfunc) 109 | throw exception("NULL == cfunc\n"); 110 | MakeMsg = cfunc; 111 | } 112 | 113 | template 114 | inline string CNodeCtl::Add_Node(const T &msg){ 115 | /* get md5 */ 116 | string new_key = Md5().get_Md5(msg); 117 | /* add node */ 118 | _Node_map[new_key] = CNode(new_key, msg); 119 | 120 | return new_key; 121 | } 122 | 123 | template 124 | inline string CNodeCtl::Add_Vir_Node(string key, const int N){ 125 | if (N < 0) 126 | throw exception("N < 0\n"); 127 | /* use HOOK func make msg */ 128 | const T& new_msg = CNodeCtl::MakeMsg(_Node_map[key].Get_real_msg(), N); 129 | string new_key = Md5().get_Md5(new_msg); 130 | /* vector push vir node */ 131 | _Node_map[new_key]._Vir_Node.push_back(new_key); 132 | 133 | return new_key; 134 | } 135 | 136 | template 137 | inline vector CNodeCtl::Del_Node(const T &msg){ 138 | string key = Md5().get_Md5(msg); 139 | /* find key */ 140 | typename _Map_Type::iterator map_it = _Node_map.find(key); 141 | /* exception handle */ 142 | if (map_it == _Node_map.end()) 143 | throw exception("not find msg\n"); 144 | /* get vir vector */ 145 | _Vec_Type vec = map_it->second._Vir_Node; 146 | /* push key */ 147 | vec.push_back(key); 148 | _Node_map.erase(map_it); 149 | return vec; 150 | } 151 | template 152 | inline T CNodeCtl::Get_Msg(const string &key){ 153 | return _Node_map[key].Get_real_msg(); 154 | } 155 | /********************************************/ 156 | 157 | //CHash code 158 | /********************************************/ 159 | template 160 | CHash::CHash(int n, const vector &vec) 161 | :_Init_count(n) 162 | { 163 | if (n != vec.size()) 164 | throw exception("init_numb error\n"); 165 | string key; 166 | string new_key; 167 | int vir_num = 3;//1 real Node have 3 vir Node 168 | /*const vec can not use ordinary iterator*/ 169 | typename vector::const_iterator vec_it = vec.begin(); 170 | 171 | for (; vec_it != vec.end(); ++vec_it){ 172 | /* add real node*/ 173 | key = _One_Node.Add_Node(*vec_it); 174 | /* add real key */ 175 | _Ip_map[key] = key; 176 | /* looping add vir node */ 177 | for (int i = 0; i < vir_num; ++i){ 178 | new_key = _One_Node.Add_Vir_Node(key, i); 179 | _Ip_map[new_key] = key; 180 | } 181 | } 182 | } 183 | 184 | template 185 | inline void CHash::Add_ser(const T &msg){ 186 | string key = _One_Node.Add_Node(msg); 187 | /* add Ip */ 188 | _Ip_map[key] = key; 189 | string new_key; 190 | /* looping push 3 vir node */ 191 | for (int i = 0; i < 3; ++i){ 192 | new_key = _One_Node.Add_Vir_Node(key, i); 193 | _Ip_map[new_key] = key; 194 | } 195 | } 196 | 197 | template 198 | inline void CHash::Del_ser(const T &msg){ 199 | /* get vir vector */ 200 | vector vir_Node(_One_Node.Del_Node(msg)); 201 | 202 | for (unsigned int i = 0; i < vir_Node.size(); ++i){ 203 | _Ip_map.erase(_Ip_map.find(vir_Node[i])); 204 | } 205 | } 206 | 207 | template 208 | inline T CHash::Find_ser(const T &msg){ 209 | string key = Md5().get_Md5(msg); 210 | /* use cosnt_iterator , can not modify */ 211 | _Map_Type::const_iterator map_it = _Ip_map.begin(); 212 | /* find a node */ 213 | for (; map_it != _Ip_map.end(); ++map_it){ 214 | if (map_it->first > key) break; 215 | } 216 | /* have noly a node */ 217 | if (map_it == _Ip_map.end()) map_it = _Ip_map.begin(); 218 | return _One_Node.Get_Msg(map_it->second); 219 | } 220 | 221 | template 222 | inline void CHash::Show_ser(){ 223 | cout << "Node : " << endl; 224 | CHash::_Map_Type::const_iterator map_it = _Ip_map.begin(); 225 | 226 | for (; map_it != _Ip_map.end(); ++map_it){ 227 | cout << map_it->first << "--->" << _One_Node.Get_Msg(map_it->second) << endl; 228 | } 229 | } 230 | /********************************************/ -------------------------------------------------------------------------------- /src/Hash/md5.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "md5.h" 3 | 4 | /* Define the static member of MD5. */ 5 | const byte MD5::PADDING[64] = { 0x80 }; 6 | const char MD5::HEX_NUMBERS[16] = { 7 | '0', '1', '2', '3', 8 | '4', '5', '6', '7', 9 | '8', '9', 'a', 'b', 10 | 'c', 'd', 'e', 'f' 11 | }; 12 | 13 | /** 14 | * @Construct a MD5 object with a string. 15 | * 16 | * @param {message} the message will be transformed. 17 | * 18 | */ 19 | MD5::MD5(const string& message) { 20 | finished = false; 21 | /* Reset number of bits. */ 22 | count[0] = count[1] = 0; 23 | /* Initialization constants. */ 24 | state[0] = 0x67452301; 25 | state[1] = 0xefcdab89; 26 | state[2] = 0x98badcfe; 27 | state[3] = 0x10325476; 28 | 29 | /* Initialization the object according to message. */ 30 | init((const byte*)message.c_str(), message.length()); 31 | } 32 | 33 | /** 34 | * @Generate md5 digest. 35 | * 36 | * @return the message-digest. 37 | * 38 | */ 39 | const byte* MD5::getDigest() { 40 | if (!finished) { 41 | finished = true; 42 | 43 | byte bits[8]; 44 | bit32 oldState[4]; 45 | bit32 oldCount[2]; 46 | bit32 index, padLen; 47 | 48 | /* Save current state and count. */ 49 | memcpy(oldState, state, 16); 50 | memcpy(oldCount, count, 8); 51 | 52 | /* Save number of bits */ 53 | encode(count, bits, 8); 54 | 55 | /* Pad out to 56 mod 64. */ 56 | index = (bit32)((count[0] >> 3) & 0x3f); 57 | padLen = (index < 56) ? (56 - index) : (120 - index); 58 | init(PADDING, padLen); 59 | 60 | /* Append length (before padding) */ 61 | init(bits, 8); 62 | 63 | /* Store state in digest */ 64 | encode(state, digest, 16); 65 | 66 | /* Restore current state and count. */ 67 | memcpy(state, oldState, 16); 68 | memcpy(count, oldCount, 8); 69 | } 70 | return digest; 71 | } 72 | 73 | /** 74 | * @Initialization the md5 object, processing another message block, 75 | * and updating the context. 76 | * 77 | * @param {input} the input message. 78 | * 79 | * @param {len} the number btye of message. 80 | * 81 | */ 82 | void MD5::init(const byte* input, size_t len) { 83 | 84 | bit32 i, index, partLen; 85 | 86 | finished = false; 87 | 88 | /* Compute number of bytes mod 64 */ 89 | index = (bit32)((count[0] >> 3) & 0x3f); 90 | 91 | /* update number of bits */ 92 | if ((count[0] += ((bit32)len << 3)) < ((bit32)len << 3)) { 93 | ++count[1]; 94 | } 95 | count[1] += ((bit32)len >> 29); 96 | 97 | partLen = 64 - index; 98 | 99 | /* transform as many times as possible. */ 100 | if (len >= partLen) { 101 | 102 | memcpy(&buffer[index], input, partLen); 103 | transform(buffer); 104 | 105 | for (i = partLen; i + 63 < len; i += 64) { 106 | transform(&input[i]); 107 | } 108 | index = 0; 109 | 110 | } 111 | else { 112 | i = 0; 113 | } 114 | 115 | /* Buffer remaining input */ 116 | memcpy(&buffer[index], &input[i], len - i); 117 | } 118 | 119 | /** 120 | * @MD5 basic transformation. Transforms state based on block. 121 | * 122 | * @param {block} the message block. 123 | */ 124 | void MD5::transform(const byte block[64]) { 125 | 126 | bit32 a = state[0], b = state[1], c = state[2], d = state[3], x[16]; 127 | 128 | decode(block, x, 64); 129 | 130 | /* Round 1 */ 131 | FF(a, b, c, d, x[0], s11, 0xd76aa478); 132 | FF(d, a, b, c, x[1], s12, 0xe8c7b756); 133 | FF(c, d, a, b, x[2], s13, 0x242070db); 134 | FF(b, c, d, a, x[3], s14, 0xc1bdceee); 135 | FF(a, b, c, d, x[4], s11, 0xf57c0faf); 136 | FF(d, a, b, c, x[5], s12, 0x4787c62a); 137 | FF(c, d, a, b, x[6], s13, 0xa8304613); 138 | FF(b, c, d, a, x[7], s14, 0xfd469501); 139 | FF(a, b, c, d, x[8], s11, 0x698098d8); 140 | FF(d, a, b, c, x[9], s12, 0x8b44f7af); 141 | FF(c, d, a, b, x[10], s13, 0xffff5bb1); 142 | FF(b, c, d, a, x[11], s14, 0x895cd7be); 143 | FF(a, b, c, d, x[12], s11, 0x6b901122); 144 | FF(d, a, b, c, x[13], s12, 0xfd987193); 145 | FF(c, d, a, b, x[14], s13, 0xa679438e); 146 | FF(b, c, d, a, x[15], s14, 0x49b40821); 147 | 148 | /* Round 2 */ 149 | GG(a, b, c, d, x[1], s21, 0xf61e2562); 150 | GG(d, a, b, c, x[6], s22, 0xc040b340); 151 | GG(c, d, a, b, x[11], s23, 0x265e5a51); 152 | GG(b, c, d, a, x[0], s24, 0xe9b6c7aa); 153 | GG(a, b, c, d, x[5], s21, 0xd62f105d); 154 | GG(d, a, b, c, x[10], s22, 0x2441453); 155 | GG(c, d, a, b, x[15], s23, 0xd8a1e681); 156 | GG(b, c, d, a, x[4], s24, 0xe7d3fbc8); 157 | GG(a, b, c, d, x[9], s21, 0x21e1cde6); 158 | GG(d, a, b, c, x[14], s22, 0xc33707d6); 159 | GG(c, d, a, b, x[3], s23, 0xf4d50d87); 160 | GG(b, c, d, a, x[8], s24, 0x455a14ed); 161 | GG(a, b, c, d, x[13], s21, 0xa9e3e905); 162 | GG(d, a, b, c, x[2], s22, 0xfcefa3f8); 163 | GG(c, d, a, b, x[7], s23, 0x676f02d9); 164 | GG(b, c, d, a, x[12], s24, 0x8d2a4c8a); 165 | 166 | /* Round 3 */ 167 | HH(a, b, c, d, x[5], s31, 0xfffa3942); 168 | HH(d, a, b, c, x[8], s32, 0x8771f681); 169 | HH(c, d, a, b, x[11], s33, 0x6d9d6122); 170 | HH(b, c, d, a, x[14], s34, 0xfde5380c); 171 | HH(a, b, c, d, x[1], s31, 0xa4beea44); 172 | HH(d, a, b, c, x[4], s32, 0x4bdecfa9); 173 | HH(c, d, a, b, x[7], s33, 0xf6bb4b60); 174 | HH(b, c, d, a, x[10], s34, 0xbebfbc70); 175 | HH(a, b, c, d, x[13], s31, 0x289b7ec6); 176 | HH(d, a, b, c, x[0], s32, 0xeaa127fa); 177 | HH(c, d, a, b, x[3], s33, 0xd4ef3085); 178 | HH(b, c, d, a, x[6], s34, 0x4881d05); 179 | HH(a, b, c, d, x[9], s31, 0xd9d4d039); 180 | HH(d, a, b, c, x[12], s32, 0xe6db99e5); 181 | HH(c, d, a, b, x[15], s33, 0x1fa27cf8); 182 | HH(b, c, d, a, x[2], s34, 0xc4ac5665); 183 | 184 | /* Round 4 */ 185 | II(a, b, c, d, x[0], s41, 0xf4292244); 186 | II(d, a, b, c, x[7], s42, 0x432aff97); 187 | II(c, d, a, b, x[14], s43, 0xab9423a7); 188 | II(b, c, d, a, x[5], s44, 0xfc93a039); 189 | II(a, b, c, d, x[12], s41, 0x655b59c3); 190 | II(d, a, b, c, x[3], s42, 0x8f0ccc92); 191 | II(c, d, a, b, x[10], s43, 0xffeff47d); 192 | II(b, c, d, a, x[1], s44, 0x85845dd1); 193 | II(a, b, c, d, x[8], s41, 0x6fa87e4f); 194 | II(d, a, b, c, x[15], s42, 0xfe2ce6e0); 195 | II(c, d, a, b, x[6], s43, 0xa3014314); 196 | II(b, c, d, a, x[13], s44, 0x4e0811a1); 197 | II(a, b, c, d, x[4], s41, 0xf7537e82); 198 | II(d, a, b, c, x[11], s42, 0xbd3af235); 199 | II(c, d, a, b, x[2], s43, 0x2ad7d2bb); 200 | II(b, c, d, a, x[9], s44, 0xeb86d391); 201 | 202 | state[0] += a; 203 | state[1] += b; 204 | state[2] += c; 205 | state[3] += d; 206 | } 207 | 208 | /** 209 | * @Encodes input (unsigned long) into output (byte). 210 | * 211 | * @param {input} usigned long. 212 | * 213 | * @param {output} byte. 214 | * 215 | * @param {length} the length of input. 216 | * 217 | */ 218 | void MD5::encode(const bit32* input, byte* output, size_t length) { 219 | 220 | for (size_t i = 0, j = 0; j < length; ++i, j += 4) { 221 | output[j] = (byte)(input[i] & 0xff); 222 | output[j + 1] = (byte)((input[i] >> 8) & 0xff); 223 | output[j + 2] = (byte)((input[i] >> 16) & 0xff); 224 | output[j + 3] = (byte)((input[i] >> 24) & 0xff); 225 | } 226 | } 227 | 228 | /** 229 | * @Decodes input (byte) into output (usigned long). 230 | * 231 | * @param {input} bytes. 232 | * 233 | * @param {output} unsigned long. 234 | * 235 | * @param {length} the length of input. 236 | * 237 | */ 238 | void MD5::decode(const byte* input, bit32* output, size_t length) { 239 | for (size_t i = 0, j = 0; j < length; ++i, j += 4) { 240 | output[i] = ((bit32)input[j]) | (((bit32)input[j + 1]) << 8) | 241 | (((bit32)input[j + 2]) << 16) | (((bit32)input[j + 3]) << 24); 242 | } 243 | } 244 | 245 | 246 | /** 247 | * @Convert digest to string value. 248 | * 249 | * @return the hex string of digest. 250 | * 251 | */ 252 | string MD5::toStr() { 253 | const byte* digest_ = getDigest(); 254 | string str; 255 | str.reserve(16 << 1); 256 | for (size_t i = 0; i < 16; ++i) { 257 | int t = digest_[i]; 258 | int a = t / 16; 259 | int b = t % 16; 260 | str.append(1, HEX_NUMBERS[a]); 261 | str.append(1, HEX_NUMBERS[b]); 262 | } 263 | return str; 264 | } 265 | -------------------------------------------------------------------------------- /src/Hash/md5.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | #ifndef MD5_H 4 | #define MD5_H 5 | /* Parameters of MD5. */ 6 | #define s11 7 7 | #define s12 12 8 | #define s13 17 9 | #define s14 22 10 | #define s21 5 11 | #define s22 9 12 | #define s23 14 13 | #define s24 20 14 | #define s31 4 15 | #define s32 11 16 | #define s33 16 17 | #define s34 23 18 | #define s41 6 19 | #define s42 10 20 | #define s43 15 21 | #define s44 21 22 | 23 | /** 24 | * @Basic MD5 functions. 25 | * 26 | * @param there bit32. 27 | * 28 | * @return one bit32. 29 | */ 30 | #define F(x, y, z) (((x) & (y)) | ((~x) & (z))) 31 | #define G(x, y, z) (((x) & (z)) | ((y) & (~z))) 32 | #define H(x, y, z) ((x) ^ (y) ^ (z)) 33 | #define I(x, y, z) ((y) ^ ((x) | (~z))) 34 | 35 | /** 36 | * @Rotate Left. 37 | * 38 | * @param {num} the raw number. 39 | * 40 | * @param {n} rotate left n. 41 | * 42 | * @return the number after rotated left. 43 | */ 44 | #define ROTATELEFT(num, n) (((num) << (n)) | ((num) >> (32-(n)))) 45 | 46 | /** 47 | * @Transformations for rounds 1, 2, 3, and 4. 48 | */ 49 | #define FF(a, b, c, d, x, s, ac) { \ 50 | (a) += F((b), (c), (d)) + (x)+ac; \ 51 | (a) = ROTATELEFT((a), (s)); \ 52 | (a) += (b); \ 53 | } 54 | #define GG(a, b, c, d, x, s, ac) { \ 55 | (a) += G((b), (c), (d)) + (x)+ac; \ 56 | (a) = ROTATELEFT((a), (s)); \ 57 | (a) += (b); \ 58 | } 59 | #define HH(a, b, c, d, x, s, ac) { \ 60 | (a) += H((b), (c), (d)) + (x)+ac; \ 61 | (a) = ROTATELEFT((a), (s)); \ 62 | (a) += (b); \ 63 | } 64 | #define II(a, b, c, d, x, s, ac) { \ 65 | (a) += I((b), (c), (d)) + (x)+ac; \ 66 | (a) = ROTATELEFT((a), (s)); \ 67 | (a) += (b); \ 68 | } 69 | 70 | #include 71 | #include 72 | 73 | using std::string; 74 | 75 | /* Define of btye.*/ 76 | typedef unsigned char byte; 77 | /* Define of byte. */ 78 | typedef unsigned int bit32; 79 | 80 | class MD5 { 81 | public: 82 | /* Construct a MD5 object with a string. */ 83 | MD5(const string& message); 84 | 85 | /* Generate md5 digest. */ 86 | const byte* getDigest(); 87 | 88 | /* Convert digest to string value */ 89 | string toStr(); 90 | 91 | private: 92 | /* Initialization the md5 object, processing another message block, 93 | * and updating the context.*/ 94 | void init(const byte* input, size_t len); 95 | 96 | /* MD5 basic transformation. Transforms state based on block. */ 97 | void transform(const byte block[64]); 98 | 99 | /* Encodes input (usigned long) into output (byte). */ 100 | void encode(const bit32* input, byte* output, size_t length); 101 | 102 | /* Decodes input (byte) into output (usigned long). */ 103 | void decode(const byte* input, bit32* output, size_t length); 104 | 105 | private: 106 | /* Flag for mark whether calculate finished. */ 107 | bool finished; 108 | 109 | /* state (ABCD). */ 110 | bit32 state[4]; 111 | 112 | /* number of bits, low-order word first. */ 113 | bit32 count[2]; 114 | 115 | /* input buffer. */ 116 | byte buffer[64]; 117 | 118 | /* message digest. */ 119 | byte digest[16]; 120 | 121 | /* padding for calculate. */ 122 | static const byte PADDING[64]; 123 | 124 | /* Hex numbers. */ 125 | static const char HEX_NUMBERS[16]; 126 | }; 127 | 128 | #endif // MD5_H 129 | -------------------------------------------------------------------------------- /src/Hash/test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "hash.h" 3 | using namespace std; 4 | 5 | string func(const string &str, int n){ 6 | char buff[100] = ""; 7 | sprintf(buff, "%s#%d", str.c_str(), n); 8 | return string(buff); 9 | } 10 | 11 | int main(){ 12 | vector vs; 13 | vs.push_back("192.168.1.34:8000"); 14 | vs.push_back("192.168.1.35:8000"); 15 | vs.push_back("192.168.1.35:8001"); 16 | vs.push_back("192.168.1.36:8003"); 17 | vs.push_back("192.168.1.36:8004"); 18 | vs.push_back("127.0.0.1:8000"); 19 | CNodeCtl::Set_Fun(func); 20 | //CHash* hash = CHash::Get_ip_map(6, vs); 21 | CHash hash(6, vs); 22 | hash.Show_ser(); 23 | 24 | string str; 25 | cout << "Msg:"; 26 | bool isruning = true; 27 | int count = 3; 28 | while (isruning){ 29 | cin >> str; 30 | cout << "GetSer: " << hash.Find_ser(str) << endl; 31 | hash.Add_ser(str); 32 | if (!--count) 33 | isruning = false; 34 | if (count != 1) 35 | cout << "Msg: "; 36 | else { 37 | string s; 38 | cout << "del :"; 39 | cin >> s; 40 | try{ 41 | hash.Del_ser(s); 42 | } 43 | catch (exception str){ 44 | cout << str.what() << endl; 45 | } 46 | } 47 | 48 | } 49 | 50 | return 0; 51 | } -------------------------------------------------------------------------------- /src/HttpControl/head.h: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | > File Name: head.h 3 | > Author: Darkfaker 4 | > Mail: Darkfaker1024@163.com 5 | > Created Time: Wed 11 Jul 2018 04:00:58 PM CST 6 | ************************************************************************/ 7 | 8 | #ifndef _HEAD_H 9 | #define _HEAD_H 10 | /*c++*/ 11 | /********************/ 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | /*c*/ 26 | /*******************/ 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | 41 | 42 | #endif 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /src/HttpControl/http_control.cpp: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | > File Name: http_control.cpp 3 | > Author:Darkfaker 4 | > Mail:Darkfaker1024@163.com 5 | > Created Time: Fri 27 Jul 2018 07:27:27 PM CST 6 | ************************************************************************/ 7 | 8 | #include 9 | #include "http_control.h" 10 | 11 | using namespace std; 12 | 13 | string Control_Http::get_Line(const string &data){ 14 | size_t index = data.find("\r\n"); 15 | if (index == data.npos) 16 | throw "http format error\n"; 17 | return string(data.substr(0, index)); 18 | } 19 | 20 | string Control_Http::get_Head(const string &data){ 21 | size_t index = data.find("\r\n"); 22 | if (index == data.npos) 23 | throw "http format error\n"; 24 | return string(data.substr(index)); 25 | } 26 | 27 | void Control_Http::make_Respons(){ 28 | /*get line*/ 29 | if (_flag == needLine){ 30 | size_t index = _data_buff.find(" "); 31 | if (index == _data_buff.npos) 32 | throw "http format error\n"; 33 | ((_ip_Item_buf->http_line)->request_method).reserve(16); 34 | ((_ip_Item_buf->http_line)->request_method) 35 | = _data_buff.substr(0, index); 36 | 37 | index = _data_buff.find(" ", index); 38 | if (index == _data_buff.npos) 39 | throw "http format error\n"; 40 | size_t index_end = _data_buff.length() - 1; 41 | if (index_end == _data_buff.npos) 42 | throw "http format error\n"; 43 | ((_ip_Item_buf->http_line)->protocol_version).reserve(16); 44 | ((_ip_Item_buf->http_line)->protocol_version) 45 | = _data_buff.substr(index + 1, index_end - index); 46 | } 47 | /*get head*/ 48 | else if (_flag == needHead){ 49 | size_t index = _data_buff.find(" "); 50 | if (index == _data_buff.npos) 51 | throw "http format error\n"; 52 | ((_ip_Item_buf->http_head->http_line_info).request_method).reserve(16); 53 | ((_ip_Item_buf->http_line)->request_method) 54 | = _data_buff.substr(0, index); 55 | 56 | index = _data_buff.find(" ", index); 57 | if (index == _data_buff.npos) 58 | throw "http format error\n"; 59 | size_t index_end = _data_buff.find("\r\n", index); 60 | if (index_end == _data_buff.npos) 61 | throw "http format error\n"; 62 | ((_ip_Item_buf->http_head->http_line_info).protocol_version).reserve(16); 63 | ((_ip_Item_buf->http_line)->protocol_version) 64 | = _data_buff.substr(index + 1, index_end - index); 65 | 66 | index = _data_buff.find("\n", index_end) + 1; 67 | index_end = _data_buff.find(" ", index); 68 | if (index == _data_buff.npos || index_end == _data_buff.npos) 69 | throw "http format error\n"; 70 | (_ip_Item_buf->http_head)->accept_langeuage.reserve(16); 71 | (_ip_Item_buf->http_head)->accept_langeuage 72 | = _data_buff.substr(index, index_end - index); 73 | 74 | index = index_end; 75 | index_end = _data_buff.find("\r\n", index_end); 76 | if (index_end == _data_buff.npos) 77 | throw "http format error\n"; 78 | (_ip_Item_buf->http_head)->connection_type.reserve(16); 79 | (_ip_Item_buf->http_head)->connection_type 80 | = _data_buff.substr(index + 1, index_end - index); 81 | } 82 | } 83 | 84 | bool Control_Http::judge_file_exist(const string &file_name){ 85 | fstream file(file_name, ios::in); 86 | if (file) 87 | return true; 88 | return false; 89 | } 90 | 91 | void Control_Http::show(){ 92 | if (_flag == needLine){ 93 | cout << _ip_Item_buf->http_line->request_method << endl; 94 | cout << _ip_Item_buf->http_line->protocol_version << endl; 95 | } 96 | else if (_flag == needHead){ 97 | cout << "1: " << _ip_Item_buf->http_head->http_line_info.request_method << endl; 98 | cout << "2: " << _ip_Item_buf->http_head->http_line_info.protocol_version << endl; 99 | cout << "3: " << _ip_Item_buf->http_head->connection_type << endl; 100 | cout << "4: " << _ip_Item_buf->http_head->accept_langeuage << endl; 101 | } 102 | } 103 | 104 | UN_LONG Control_Http::getSize(int s){ 105 | return (sizeof(ipItem_head_t)+s) > MAX_FILE_SIZE ? (sizeof(ipItem_head_t)+s) : MAX_FILE_SIZE; 106 | } 107 | 108 | -------------------------------------------------------------------------------- /src/HttpControl/http_control.h: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | > File Name: http_control.cpp 3 | > Author: Darkfaker 4 | > Mail: Darkfaker1024@163.com 5 | > Created Time: Thu 26 Jul 2018 07:15:02 PM CST 6 | ************************************************************************/ 7 | #ifndef _HTTP_CONTROL_H 8 | #define _HTTP_CONTROL_H 9 | #include 10 | #include "../NginxPool/Nginx.h" 11 | #include "head.h" 12 | #include "myallocator.h" 13 | using namespace std; 14 | 15 | typedef unsigned long long UN_LONG; 16 | UN_LONG const MAX_FILE_SIZE = 1024 * 1024 * 4; 17 | 18 | /*struct HTTP line*/ 19 | typedef struct ipItem_line_s{ 20 | uchar *line_pos;/*the pos of line in pool*/ 21 | uchar *line_end;/*the end of line in pool*/ 22 | string request_method;/*the request method of cli*/ 23 | string status_mask;/*the status mask of cli*/ 24 | string protocol_version;/*the protocal version of cli(ipv4/ipv6)*/ 25 | }ipItem_line_s; 26 | typedef ipItem_line_s ipItem_line_t; 27 | 28 | 29 | /*struct file*/ 30 | typedef struct file_info_s{ 31 | int file_fd;/*file fd*/ 32 | UN_LONG file_size;/*file size*/ 33 | UN_LONG file_pos;/*the pos of file in Disk*/ 34 | UN_LONG file_end;/*the end of file in Disk*/ 35 | }file_info_s; 36 | typedef file_info_s file_info_t; 37 | 38 | 39 | /*struct HTTP head*/ 40 | typedef struct ipItem_head_s{ 41 | ipItem_line_s http_line_info;/*struct HTTP line*/ 42 | string accept_langeuage;/*the langeuage of cli use*/ 43 | string connection_type;/*the connextion type of cli*/ 44 | file_info_t file_information;/*struct file*/ 45 | }ipItem_head_s; 46 | typedef ipItem_head_s ipItem_head_t; 47 | 48 | 49 | /*struct ip Item*/ 50 | typedef union ipItem_s{ 51 | /*request line*/ 52 | ipItem_line_t *http_line; 53 | /*request head*/ 54 | ipItem_head_t *http_head; 55 | }ipItem_s; 56 | typedef ipItem_s ipItem_t; 57 | 58 | 59 | /*class HTTP Control*/ 60 | class Control_Http{ 61 | public: 62 | #define needLine true 63 | #define needHead false 64 | 65 | typedef myallocator _Pool_Type; 66 | private: 67 | ipItem_t *_ip_Item_buf; 68 | UN_LONG _max_file_size; 69 | string _data_buff;/*tmp buf*/ 70 | _Pool_Type *pool;/*memory pool*/ 71 | bool _flag;/*line or head*/ 72 | public: 73 | Control_Http(const string &data, bool f) 74 | : _max_file_size(MAX_FILE_SIZE) 75 | , _flag(f) 76 | { 77 | /*create memory pool*/ 78 | pool = new _Pool_Type(getSize(data.length())); 79 | /*allocate memory*/ 80 | ipItem_t *ptr = (ipItem_t*)pool->allocate(sizeof(ipItem_t) + 128); 81 | if (NULL == ptr) 82 | throw "memory is empty\n"; 83 | /*create tmp buf*/ 84 | _ip_Item_buf = new ipItem_t(); 85 | /*choose line or head*/ 86 | if (_flag == needLine){ 87 | _ip_Item_buf->http_line = new ipItem_line_t(); 88 | _data_buff = get_Line(data); 89 | } 90 | else if (_flag == needHead){ 91 | _ip_Item_buf->http_head = new ipItem_head_t(); 92 | _data_buff = get_Line(data); 93 | _data_buff += get_Head(data); 94 | } 95 | /*make respons*/ 96 | make_Respons(); 97 | /*construct ip Item*/ 98 | pool->construct(ptr, *_ip_Item_buf); 99 | /*clear buff*/ 100 | _data_buff.clear(); 101 | /*delete tmp buff*/ 102 | delete _ip_Item_buf; 103 | /*use the memory pool ip Item*/ 104 | _ip_Item_buf = ptr; 105 | } 106 | ~Control_Http(){ 107 | pool->destroy(_ip_Item_buf); 108 | pool->deallocate(_ip_Item_buf); 109 | } 110 | /*get HTTP line*/ 111 | string get_Line(const string &data); 112 | /*get HTTP head*/ 113 | string get_Head(const string &data); 114 | /*make respons*/ 115 | void make_Respons(); 116 | /*juege the file is exist*/ 117 | bool judge_file_exist(const string &file_name); 118 | void show(); 119 | /*sum size*/ 120 | UN_LONG getSize(int s); 121 | }; 122 | 123 | #endif 124 | 125 | 126 | 127 | 128 | -------------------------------------------------------------------------------- /src/HttpControl/main.cpp: -------------------------------------------------------------------------------- 1 | #include "Nginx.h" 2 | #include "http_control.h" 3 | #include "myallocator.h" 4 | #include 5 | #include 6 | using namespace std; 7 | 8 | int main(){ 9 | try{ 10 | Control_Http http(string("HTTP/ 200 OK\r\ntype zh-cn\r\n"), 0); 11 | http.show(); 12 | } 13 | catch (const char* str){ 14 | cout << str << endl; 15 | }; 16 | 17 | 18 | system("pause"); 19 | 20 | return 0; 21 | } -------------------------------------------------------------------------------- /src/HttpControl/myallocator.h: -------------------------------------------------------------------------------- 1 | #ifndef _ALLOCATOR_H 2 | #define _ALLOCATOR_H 3 | 4 | #include "../NginxPool/Nginx.h" 5 | #include "head.h" 6 | 7 | /*Define the default memory management method*/ 8 | template 9 | class myallocator{ 10 | public: 11 | typedef unsigned long long UN_LONG; 12 | private: 13 | Ngx *_Ngx; 14 | public: 15 | myallocator(UN_LONG size){ 16 | _Ngx = new NgxMemPool(size); 17 | } 18 | /*delete*/ 19 | ~myallocator(){ 20 | delete _Ngx; 21 | _Ngx.~NgxMemPool(); 22 | _Ngx = NULL; 23 | } 24 | void construct(void *ptr, const T &val){ 25 | new (ptr)T(val); 26 | } 27 | 28 | void construct(void *ptr){ 29 | new (ptr)T(); 30 | } 31 | void destroy(T *ptr){ 32 | ptr->~T(); 33 | } 34 | 35 | void* allocate(size_t size){ 36 | return _Ngx->my_ngx_palloc(size); 37 | } 38 | /*reset memory pool*/ 39 | void deallocate(void *ptr){ 40 | _Ngx->my_ngx_reset_pool(); 41 | } 42 | }; 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /src/NginxPool/Nginx.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Darkfaker/filetransfer/8ba2bced677b43f0608aabbbfedbf12298bf5da5/src/NginxPool/Nginx.cpp -------------------------------------------------------------------------------- /src/NginxPool/Nginx.h: -------------------------------------------------------------------------------- 1 | #ifndef _NGINX_H 2 | #define _NGINX_H 3 | 4 | #include "NginxPoolTypeInfo.h" 5 | 6 | /*class memory pool*/ 7 | class NgxMemPool{ 8 | public: 9 | typedef shared_ptr> _Smart_Ptr_Type; 10 | typedef weak_ptr> _Weak_Ptr_Type; 11 | private: 12 | my_ngx_pool_t *_pool; 13 | _Smart_Ptr_Type _pool_Number_Ptr; 14 | _Weak_Ptr_Type _pool_Number_Weak_Ptr; 15 | public: 16 | NgxMemPool(size_t size){ 17 | cout << "NgxMemPool(size_t size)" << endl; 18 | _pool = my_ngx_create_pool(size); 19 | } 20 | 21 | ~NgxMemPool(){ 22 | cout << "~NgxMemPool()" << endl; 23 | my_ngx_destroy_pool(); 24 | } 25 | /*reset memory pool*/ 26 | void my_ngx_reset_pool(); 27 | /*align pool*/ 28 | void *my_ngx_palloc(size_t size); 29 | /*not align*/ 30 | void *my_ngx_pnalloc(size_t size); 31 | my_ngx_pool_cleanup_t *my_ngx_pool_cleanup_add(size_t size); 32 | private: 33 | /*create mempry pool*/ 34 | my_ngx_pool_t *my_ngx_create_pool(size_t size); 35 | /*alloc memory*/ 36 | void *my_ngx_alloc(size_t size); 37 | void *my_ngx_calloc(size_t size); 38 | /*alloc small memory*/ 39 | void *my_ngx_palloc_small(size_t size, bool align); 40 | /*alloc new block*/ 41 | void *my_ngx_palloc_block(size_t size); 42 | /*alloc large memory*/ 43 | void *my_ngx_palloc_large(size_t size); 44 | /*free memory*/ 45 | uint my_ngx_pfree(void *p); 46 | /*destroy pool*/ 47 | void my_ngx_destroy_pool(); 48 | }; 49 | 50 | 51 | #endif -------------------------------------------------------------------------------- /src/NginxPool/NginxPoolTypeInfo.h: -------------------------------------------------------------------------------- 1 | #ifndef _NGINXPOOLTYPEINFO_H 2 | #define _NGINXPOOLTYPEINFO_H 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | const int ngx_pagesize = 4096; 9 | const int NGX_ALIGN = sizeof(unsigned long); 10 | /*my data type*/ 11 | typedef unsigned char uchar; 12 | typedef unsigned long ulong; 13 | typedef unsigned int uint; 14 | 15 | /*typedef struct*/ 16 | typedef struct my_ngx_data_s my_ngx_data_t; 17 | typedef struct my_ngx_pool_s my_ngx_pool_t; 18 | typedef struct pool_count_s pool_count_t; 19 | typedef struct my_ngx_pool_large_s my_ngx_pool_large_t; 20 | typedef struct my_ngx_pool_cleanup_s my_ngx_pool_cleanup_t; 21 | typedef void(*my_ngx_pool_cleanup_pt)(void *data); 22 | 23 | /*align*/ 24 | inline ulong my_ngx_align(uchar d, ulong a){ 25 | return (((d)+(a - 1)) & ~(a - 1)); 26 | } 27 | inline uchar* my_ngx_align_ptr(uchar *p, ulong a){ 28 | return ((uchar *)(((uint)(p)+((uint)a - 1)) & ~((uint)a - 1))); 29 | } 30 | 31 | /*the number of pool*/ 32 | typedef struct pool_count_s{ 33 | uint number; 34 | shared_ptr poolPtr; 35 | weak_ptr weak_poolPtr; 36 | }pool_count_s; 37 | 38 | /*struct data*/ 39 | typedef struct my_ngx_data_s{ 40 | uchar *last; 41 | uchar *end; 42 | my_ngx_pool_t *next; 43 | uint failed; 44 | }my_ngx_data_t; 45 | 46 | /*struct pool*/ 47 | typedef struct my_ngx_pool_s{ 48 | my_ngx_data_t data; 49 | size_t max; 50 | my_ngx_pool_t *current; 51 | my_ngx_pool_large_t *large; 52 | my_ngx_pool_cleanup_t *cleanup; 53 | uint number; 54 | }my_ngx_pool_t; 55 | 56 | /*struct large*/ 57 | typedef struct my_ngx_pool_large_s{ 58 | my_ngx_pool_large_t *next; 59 | void *alloc; 60 | }my_ngx_pool_large_t; 61 | 62 | /*struct cleanup*/ 63 | typedef struct my_ngx_pool_cleanup_s{ 64 | my_ngx_pool_cleanup_pt hander; 65 | void *data; 66 | my_ngx_pool_cleanup_t *next; 67 | }my_ngx_pool_cleanup_t; 68 | 69 | 70 | #endif -------------------------------------------------------------------------------- /src/cli/client/cli.cpp: -------------------------------------------------------------------------------- 1 | #define _CRT_SECURE_NO_WARNINGS 2 | #include "LinuxFun" 3 | #include "STL" 4 | #include "sockpair.h" 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | using namespace std; 11 | 12 | int sockfd_init(); 13 | typedef unsigned long long UNLL; 14 | void put_file(int, int, int); 15 | void get_file(int, int, int); 16 | 17 | const int B_SIZE = 1024; 18 | //fork and iostream 19 | class ForkExecv{ 20 | public: 21 | ForkExecv(){} 22 | ~ForkExecv(){} 23 | /*fork sockpair control*/ 24 | string Fork_pro_comd(const string &comd){ 25 | char buff[B_SIZE]; 26 | string tmpbuff; 27 | FILE *fp; 28 | comd; 29 | fp = dpopen(comd.c_str()); 30 | if (fp == NULL){ 31 | perror("dpopen error"); 32 | exit(1); 33 | } 34 | if (dphalfclose(fp) < 0){ 35 | perror("dphalfclose error"); 36 | exit(1); 37 | } 38 | while (1){ 39 | if (fgets(buff, B_SIZE, fp) == NULL) 40 | break; 41 | tmpbuff += buff; 42 | } 43 | return string(tmpbuff); 44 | dpclose(fp); 45 | } 46 | private: 47 | }; 48 | //MD5 Control 49 | class CMd5 : public ForkExecv{ 50 | public: 51 | typedef unordered_multimap _Mytype; 52 | static CMd5 *GetMd5(){ return &_md5; } 53 | ~CMd5(){} 54 | /*make md5*/ 55 | string make_md5(const string &file_name){ 56 | string _comd("md5sum"); 57 | _comd += " "; 58 | _comd += file_name; 59 | _md5_Str = ForkExecv::Fork_pro_comd(_comd); 60 | 61 | string::iterator it = _md5_Str.begin(); 62 | string tmp; 63 | 64 | int id = 0; 65 | while (_md5_Str[id] != '\n') 66 | ++id; 67 | 68 | for (id; _md5_Str[id] != '\0'; ++id) 69 | tmp.push_back(_md5_Str[id]); 70 | tmp.erase(tmp.begin()); 71 | id = file_name.size() + 3; 72 | while (id){ 73 | tmp.pop_back(); 74 | --id; 75 | } 76 | it = _comd.begin(); 77 | for (; it != _comd.end(); ++it) 78 | it = _comd.erase(it); 79 | cout << "_md5_str: " << tmp << endl; 80 | return string(tmp); 81 | } 82 | /*insert*/ 83 | void insert_md5(const string &m, const string &file){ 84 | _Md5_map.insert(make_pair(m, file)); 85 | } 86 | /*del*/ 87 | void del_md5(const string &m){ 88 | _Md5_map.erase(m); 89 | } 90 | _Mytype::iterator find_md5(const string &m){ 91 | return _Md5_map.find(m); 92 | } 93 | _Mytype::iterator get_end(){ 94 | return _Md5_map.end(); 95 | } 96 | _Mytype::iterator get_begin(){ 97 | return _Md5_map.begin(); 98 | } 99 | private: 100 | unordered_multimap _Md5_map; 101 | CMd5(){}; 102 | static CMd5 _md5; 103 | string _md5_Str; 104 | }; 105 | CMd5 CMd5::_md5; 106 | 107 | //cli control 108 | class Client //:public CFile{ 109 | public: 110 | Client(){ 111 | _sockfd = sockfd_init(); 112 | _md5 = CMd5::GetMd5(); 113 | _comd = new char[32](); 114 | } 115 | ~Client(){} 116 | void cliRun(); 117 | void putCtl(char **myargv); 118 | void getCtl(char **myargv); 119 | private: 120 | int _sockfd; 121 | CMd5 *_md5; 122 | char *_comd; 123 | }; 124 | /*Runing*/ 125 | void Client::cliRun(){ 126 | while (1){ 127 | cout << "+------------------------------------------+" << endl; 128 | cout << "input:" << endl; 129 | 130 | fgets(_comd, 32, stdin); 131 | _comd[strlen(_comd) - 1] = 0; 132 | 133 | cout << "_comd :" << _comd << endl; 134 | char *myargv[10] = { 0 }; 135 | char *s = strtok(_comd, " "); 136 | if (NULL == s) 137 | continue; 138 | myargv[0] = s; 139 | int i = 0; 140 | while (NULL != (s = strtok(NULL, " "))) 141 | myargv[++i] = s; 142 | 143 | string cmd(myargv[0]); 144 | if (cmd == "end"){ 145 | close(_sockfd); 146 | break; 147 | } 148 | else if (cmd == "clear"){ 149 | system("pause"); 150 | close(_sockfd); 151 | } 152 | else if (cmd == "get"){ 153 | getCtl(myargv); 154 | } 155 | else if (cmd == "put"){ 156 | putCtl(myargv); 157 | } 158 | else{ 159 | char buff[2047]; 160 | send(_sockfd, _comd, strlen(_comd), 0); 161 | int num = recv(_sockfd, buff, 2047, 0); 162 | if (num <= 0){ 163 | close(_sockfd); 164 | continue; 165 | } 166 | printf("%s\n", buff); 167 | } 168 | } 169 | } 170 | /*send file*/ 171 | inline void put_file(int sockfd, int fd, int file_size){ 172 | char buff[2]; 173 | recv(sockfd, buff, 2, 0);/// recv 1 174 | if (strncmp(buff, "no", 2) == 0) 175 | return; 176 | sendfile(sockfd, fd, NULL, file_size); 177 | close(fd); 178 | } 179 | /*get file*/ 180 | inline void get_file(int sockfd, int file_size, int fd){ 181 | cout << "get file......." << endl; 182 | send(sockfd, "ok", 2, 0);// send 1 183 | int fin_size(0); 184 | int numb(0); 185 | char *recv_buff = new char[1024](); 186 | while ((numb = recv(sockfd, recv_buff, 1024, 0)) > 0){ 187 | fin_size += numb; 188 | write(fd, recv_buff, numb); 189 | memset(recv_buff, 0, 1024); 190 | if (fin_size == file_size) 191 | break; 192 | } 193 | delete[]recv_buff; 194 | } 195 | /*put fil control*/ 196 | inline void Client::putCtl(char **myargv){ 197 | cout << "putctl:>>" << endl; 198 | string cmd(_comd); 199 | cmd += " "; 200 | cmd += myargv[1]; 201 | cmd += " "; 202 | cmd += _md5->make_md5(string(myargv[1])); 203 | 204 | int fd = open(myargv[1], O_RDONLY); 205 | if (fd == -1){ 206 | cout << "------have no file!" << endl; 207 | return; 208 | } 209 | int size = lseek(fd, 0, SEEK_END); 210 | lseek(fd, 0, SEEK_SET); 211 | 212 | char arr[32] = { 0 }; 213 | sprintf(arr, "%d", size); 214 | cmd += " "; 215 | cmd += arr; 216 | 217 | send(_sockfd, cmd.c_str(), cmd.length(), 0); 218 | put_file(_sockfd, fd, size); 219 | } 220 | /*get fil control*/ 221 | inline void Client::getCtl(char **myargv){ 222 | string cmd(myargv[0]); 223 | cmd += " "; 224 | cmd += myargv[1]; 225 | cout << "cmd: " << cmd << endl; 226 | send(_sockfd, cmd.c_str(), cmd.length(), 0); 227 | 228 | char buff[32] = { 0 }; 229 | recv(_sockfd, buff, 32, 0); 230 | cout << "buff :" << buff << endl; 231 | if (strncmp(buff, "no file", 7) == 0){ 232 | cout << "this file is not exist!" << endl; 233 | return; 234 | } 235 | else{ 236 | int size(0); 237 | sscanf(buff, "%d", &size); 238 | cout << "file_size: " << size << endl; 239 | int fd = open(myargv[1], O_WRONLY | O_CREAT, 0600); 240 | if (fd == -1) 241 | return; 242 | get_file(_sockfd, size, fd); 243 | } 244 | } 245 | 246 | 247 | int sockfd_init(){ 248 | int sockfd = socket(AF_INET, SOCK_STREAM, 0); 249 | assert(sockfd != -1); 250 | 251 | struct sockaddr_in saddr; 252 | memset(&saddr, 0, sizeof(saddr)); 253 | 254 | saddr.sin_family = AF_INET; 255 | saddr.sin_port = htons(6000); 256 | saddr.sin_addr.s_addr = inet_addr("127.0.0.1"); 257 | 258 | int res = connect(sockfd, (struct sockaddr*)&saddr, sizeof(saddr)); 259 | assert(res != -1); 260 | return sockfd; 261 | } 262 | 263 | -------------------------------------------------------------------------------- /src/cli/include/LinuxFun.h: -------------------------------------------------------------------------------- 1 | #ifndef _LINUXFUN_H 2 | #define _LINUXFUN_H 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /src/cli/include/STL.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Darkfaker/filetransfer/8ba2bced677b43f0608aabbbfedbf12298bf5da5/src/cli/include/STL.h -------------------------------------------------------------------------------- /src/cli/main.cpp: -------------------------------------------------------------------------------- 1 | #include "LinuxFun" 2 | #include "STL" 3 | #include "sockpair.h" 4 | 5 | int main() 6 | { 7 | int sockfd = sockfd_init(); 8 | 9 | Client p; 10 | p.cliRun(); 11 | return 0; 12 | } -------------------------------------------------------------------------------- /src/cli/sockpair/sockpair.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Darkfaker/filetransfer/8ba2bced677b43f0608aabbbfedbf12298bf5da5/src/cli/sockpair/sockpair.cpp -------------------------------------------------------------------------------- /src/cli/sockpair/sockpair.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _DPOPEN_H 3 | #define _DPOPEN_H 4 | 5 | #include 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | FILE *dpopen(const char *command); 12 | int dpclose(FILE *stream); 13 | int dphalfclose(FILE *stream); 14 | 15 | #ifdef __cplusplus 16 | } 17 | #endif 18 | 19 | #endif /* _DPOPEN_H */ 20 | -------------------------------------------------------------------------------- /src/jsoncpp/cppjson.h: -------------------------------------------------------------------------------- 1 | /* 2 | * cppjson - JSON (de)serialization library for C++ and STL 3 | * 4 | * Copyright 2012 Janne Kulmala 5 | * 6 | * Program code is licensed with GNU LGPL 2.1. See COPYING.LGPL file. 7 | */ 8 | #ifndef __cppjson_h 9 | #define __cppjson_h 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | namespace json { 21 | 22 | class decode_error: public std::runtime_error { 23 | public: 24 | decode_error(const std::string &what) : 25 | std::runtime_error(what) 26 | {} 27 | }; 28 | 29 | class type_error: public std::runtime_error { 30 | public: 31 | type_error(const std::string &what) : 32 | std::runtime_error(what) 33 | {} 34 | }; 35 | 36 | /* Must use the same order as type_names[] */ 37 | enum Type { 38 | JSON_NULL, 39 | JSON_STRING, 40 | JSON_INTEGER, 41 | JSON_FLOATING, 42 | JSON_BOOLEAN, 43 | JSON_OBJECT, 44 | JSON_ARRAY, 45 | JSON_LAZY_ARRAY, 46 | }; 47 | 48 | struct LazyArray; 49 | 50 | class Value; 51 | typedef std::map object_map_t; 52 | 53 | class Value { 54 | public: 55 | Value(Type type = JSON_NULL); 56 | Value(const std::string &s); 57 | Value(const char *s); 58 | Value(int i); 59 | Value(double d); 60 | Value(bool b); 61 | Value(const object_map_t &object); 62 | Value(const std::vector &array); 63 | Value(const Value &from); 64 | ~Value(); 65 | 66 | Type type() const { return m_type; } 67 | 68 | std::string as_string() const 69 | { 70 | verify_type(JSON_STRING); 71 | return *m_value.string; 72 | } 73 | int as_integer() const 74 | { 75 | verify_type(JSON_INTEGER); 76 | if (int(m_value.integer) != m_value.integer) { 77 | throw type_error("Too large a integer"); 78 | } 79 | return m_value.integer; 80 | } 81 | int64_t as_int64() const 82 | { 83 | verify_type(JSON_INTEGER); 84 | return m_value.integer; 85 | } 86 | double as_double() const 87 | { 88 | /* treat integers as numbers too */ 89 | if (m_type == JSON_INTEGER) 90 | return m_value.integer; 91 | verify_type(JSON_FLOATING); 92 | return m_value.floating; 93 | } 94 | bool as_boolean() const 95 | { 96 | verify_type(JSON_BOOLEAN); 97 | return m_value.boolean; 98 | } 99 | const object_map_t &as_object() const 100 | { 101 | verify_type(JSON_OBJECT); 102 | return *m_value.object; 103 | } 104 | const std::vector &as_array() const 105 | { 106 | verify_type(JSON_ARRAY); 107 | return *m_value.array; 108 | } 109 | const object_map_t &as_const_object() 110 | { 111 | verify_type(JSON_OBJECT); 112 | return *m_value.object; 113 | } 114 | const std::vector &as_const_array() 115 | { 116 | verify_type(JSON_ARRAY); 117 | return *m_value.array; 118 | } 119 | object_map_t &as_object() 120 | { 121 | verify_type(JSON_OBJECT); 122 | return *m_value.object; 123 | } 124 | std::vector &as_array() 125 | { 126 | verify_type(JSON_ARRAY); 127 | return *m_value.array; 128 | } 129 | 130 | /* Used to iterate lazy-loaded arrays */ 131 | Value load_next(bool *eof = NULL, bool lazy = false); 132 | 133 | const Value &get(const std::string &s) const 134 | { 135 | static Value null; 136 | verify_type(JSON_OBJECT); 137 | object_map_t::iterator i = m_value.object->find(s); 138 | if (i == m_value.object->end()) { 139 | return null; 140 | } 141 | return i->second; 142 | } 143 | Value &get(const std::string &s) 144 | { 145 | static Value null; 146 | verify_type(JSON_OBJECT); 147 | object_map_t::iterator i = m_value.object->find(s); 148 | if (i == m_value.object->end()) { 149 | return null; 150 | } 151 | return i->second; 152 | } 153 | void set(const std::string &s, const Value &val) 154 | { 155 | verify_type(JSON_OBJECT); 156 | m_value.object->insert(std::make_pair(s, val)); 157 | } 158 | 159 | void append(const Value &val) 160 | { 161 | verify_type(JSON_ARRAY); 162 | m_value.array->push_back(val); 163 | } 164 | 165 | void operator = (const Value &from); 166 | 167 | bool operator == (const Value &other) const; 168 | bool operator != (const Value &other) const; 169 | 170 | void load(std::istream &is, bool lazy = false); 171 | void load_all(std::istream &is, bool lazy = false); 172 | 173 | void write(std::ostream &os, int indent=0) const; 174 | 175 | private: 176 | Type m_type; 177 | union { 178 | std::string *string; 179 | int64_t integer; 180 | double floating; 181 | bool boolean; 182 | object_map_t *object; 183 | std::vector *array; 184 | LazyArray *lazy; 185 | } m_value; 186 | 187 | void destroy(); 188 | 189 | void verify_type(Type type) const; 190 | }; 191 | 192 | } 193 | 194 | #endif 195 | -------------------------------------------------------------------------------- /src/jsoncpp/json.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * cppjson - JSON (de)serialization library for C++ and STL 3 | * 4 | * Copyright 2012 Janne Kulmala 5 | * 6 | * Program code is licensed with GNU LGPL 2.1. See COPYING.LGPL file. 7 | */ 8 | #include "cppjson.h" 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #define FOR_EACH_CONST(type, i, cont) \ 16 | for (type::const_iterator i = (cont).begin(); i != (cont).end(); ++i) 17 | 18 | namespace json { 19 | 20 | struct LazyArray { 21 | std::istream *is; 22 | std::istream::streampos offset; 23 | }; 24 | 25 | /* Format a string, similar to sprintf() */ 26 | const std::string strf(const char *fmt, ...) 27 | { 28 | va_list vl; 29 | va_start(vl, fmt); 30 | char *buf = NULL; 31 | if (vasprintf(&buf, fmt, vl) < 0) { 32 | va_end(vl); 33 | throw std::bad_alloc(); 34 | } 35 | va_end(vl); 36 | std::string s(buf); 37 | free(buf); 38 | return s; 39 | } 40 | 41 | size_t encode_utf8(int c, uint8_t *buffer) 42 | { 43 | if (c < 0x80) { 44 | buffer[0] = c; 45 | return 1; 46 | } else if (c < 0x800) { 47 | buffer[0] = 0xC0 + ((c & 0x7C0) >> 6); 48 | buffer[1] = 0x80 + ((c & 0x03F)); 49 | return 2; 50 | } else if (c < 0x10000) { 51 | buffer[0] = 0xE0 + ((c & 0xF000) >> 12); 52 | buffer[1] = 0x80 + ((c & 0x0FC0) >> 6); 53 | buffer[2] = 0x80 + ((c & 0x003F)); 54 | return 3; 55 | } else if (c <= 0x10FFFF) { 56 | buffer[0] = 0xF0 + ((c & 0x1C0000) >> 18); 57 | buffer[1] = 0x80 + ((c & 0x03F000) >> 12); 58 | buffer[2] = 0x80 + ((c & 0x000FC0) >> 6); 59 | buffer[3] = 0x80 + ((c & 0x00003F)); 60 | return 4; 61 | } 62 | return 0; 63 | } 64 | 65 | static const char *type_names[] = { 66 | "null", 67 | "string", 68 | "integer", 69 | "floating", 70 | "boolean", 71 | "object", 72 | "array", 73 | "lazy array", 74 | }; 75 | 76 | Value::Value(Type type) : 77 | m_type(type) 78 | { 79 | switch (m_type) { 80 | case JSON_OBJECT: 81 | m_value.object = new object_map_t; 82 | break; 83 | case JSON_ARRAY: 84 | m_value.array = new std::vector; 85 | break; 86 | case JSON_NULL: 87 | break; 88 | default: 89 | /* other types can not be constructed */ 90 | assert(0); 91 | } 92 | } 93 | 94 | Value::Value(const std::string &s) : 95 | m_type(JSON_STRING) 96 | { 97 | m_value.string = new std::string(s); 98 | } 99 | 100 | Value::Value(const char *s) : 101 | m_type(JSON_STRING) 102 | { 103 | m_value.string = new std::string(s); 104 | } 105 | 106 | Value::Value(int i) : 107 | m_type(JSON_INTEGER) 108 | { 109 | m_value.integer = i; 110 | } 111 | 112 | Value::Value(double d) : 113 | m_type(JSON_FLOATING) 114 | { 115 | m_value.floating = d; 116 | } 117 | 118 | Value::Value(bool b) : 119 | m_type(JSON_BOOLEAN) 120 | { 121 | m_value.boolean = b; 122 | } 123 | 124 | Value::Value(const object_map_t &object) : 125 | m_type(JSON_OBJECT) 126 | { 127 | m_value.object = new object_map_t(object); 128 | } 129 | 130 | Value::Value(const std::vector &array) : 131 | m_type(JSON_ARRAY) 132 | { 133 | m_value.array = new std::vector(array); 134 | } 135 | 136 | Value::Value(const Value &from) : 137 | m_type(JSON_NULL) 138 | { 139 | *this = from; 140 | } 141 | 142 | Value::~Value() 143 | { 144 | destroy(); 145 | } 146 | 147 | void Value::destroy() 148 | { 149 | switch (m_type) { 150 | case JSON_STRING: 151 | delete m_value.string; 152 | break; 153 | case JSON_OBJECT: 154 | delete m_value.object; 155 | break; 156 | case JSON_ARRAY: 157 | delete m_value.array; 158 | break; 159 | case JSON_LAZY_ARRAY: 160 | delete m_value.lazy; 161 | break; 162 | case JSON_NULL: 163 | case JSON_BOOLEAN: 164 | case JSON_INTEGER: 165 | case JSON_FLOATING: 166 | break; 167 | default: 168 | assert(0); 169 | } 170 | m_type = JSON_NULL; 171 | } 172 | 173 | void Value::verify_type(Type expected) const 174 | { 175 | if (expected != m_type) { 176 | throw type_error(strf("Expected type %s, but got %s", 177 | type_names[expected], type_names[m_type])); 178 | } 179 | } 180 | 181 | void Value::operator = (const Value &from) 182 | { 183 | if (this == &from) 184 | return; 185 | destroy(); 186 | m_type = from.m_type; 187 | switch (m_type) { 188 | case JSON_NULL: 189 | break; 190 | case JSON_STRING: 191 | m_value.string = new std::string(*from.m_value.string); 192 | break; 193 | case JSON_OBJECT: 194 | m_value.object = new object_map_t(*from.m_value.object); 195 | break; 196 | case JSON_ARRAY: 197 | m_value.array = new std::vector(*from.m_value.array); 198 | break; 199 | case JSON_INTEGER: 200 | m_value.integer = from.m_value.integer; 201 | break; 202 | case JSON_FLOATING: 203 | m_value.floating = from.m_value.floating; 204 | break; 205 | case JSON_BOOLEAN: 206 | m_value.boolean = from.m_value.boolean; 207 | break; 208 | case JSON_LAZY_ARRAY: 209 | m_value.lazy = new LazyArray(*from.m_value.lazy); 210 | break; 211 | default: 212 | assert(0); 213 | } 214 | } 215 | 216 | Type cmp_type(Type type) 217 | { 218 | if (type == JSON_INTEGER) 219 | return JSON_FLOATING; 220 | return type; 221 | } 222 | 223 | bool Value::operator == (const Value &other) const 224 | { 225 | if (cmp_type(m_type) != cmp_type(other.m_type)) 226 | return false; 227 | switch (m_type) { 228 | case JSON_NULL: 229 | return true; 230 | case JSON_STRING: 231 | return *m_value.string == *other.m_value.string; 232 | case JSON_OBJECT: 233 | return *m_value.object == *other.m_value.object; 234 | case JSON_ARRAY: 235 | return *m_value.array == *other.m_value.array; 236 | case JSON_INTEGER: 237 | if (other.m_type == JSON_INTEGER) 238 | return m_value.integer == other.m_value.integer; 239 | else 240 | return m_value.integer == other.m_value.floating; 241 | case JSON_FLOATING: 242 | if (other.m_type == JSON_INTEGER) 243 | return m_value.floating == other.m_value.integer; 244 | else 245 | return m_value.floating == other.m_value.floating; 246 | case JSON_BOOLEAN: 247 | return m_value.boolean == other.m_value.boolean; 248 | default: 249 | assert(0); 250 | } 251 | } 252 | 253 | bool Value::operator != (const Value &other) const 254 | { 255 | return !(*this == other); 256 | } 257 | 258 | /* Skips over all spaces in the input. The stream can end up in EOF state. */ 259 | int skip_space(std::istream &is) 260 | { 261 | int c; 262 | while (1) { 263 | c = is.peek(); 264 | while (isspace(c)) { 265 | is.get(); 266 | c = is.peek(); 267 | } 268 | if (c == '/') { 269 | /* Skip over C++-style comments */ 270 | is.get(); 271 | if (is.get() != '/') { 272 | throw decode_error("Expected '/'"); 273 | } 274 | while (is.peek() != '\n' && !is.eof()) 275 | is.get(); 276 | } else 277 | break; 278 | } 279 | return c; 280 | } 281 | 282 | std::string load_string(std::istream &is) 283 | { 284 | std::string str; 285 | int c = is.get(); 286 | while (c != '"') { 287 | if (c == '\\') { 288 | c = is.get(); 289 | if (is.eof()) { 290 | throw decode_error("Unexpected end of input"); 291 | } 292 | switch (c) { 293 | case 'n': 294 | c = '\n'; 295 | break; 296 | case 'r': 297 | c = '\r'; 298 | break; 299 | case 't': 300 | c = '\t'; 301 | break; 302 | case 'f': 303 | c = '\f'; 304 | break; 305 | case 'b': 306 | c = '\b'; 307 | break; 308 | case '\\': 309 | case '/': 310 | case '"': 311 | /* pass through */ 312 | break; 313 | case 'u': 314 | { 315 | char code[5]; 316 | code[4] = 0; 317 | is.read(code, 4); 318 | if (is.eof()) { 319 | throw decode_error("Unexpected end of input"); 320 | } 321 | std::istringstream parser(code); 322 | parser >> std::hex >> c; 323 | if (!parser) { 324 | throw decode_error("Invalid unicode"); 325 | } 326 | parser.get(); 327 | if (!parser.eof()) { 328 | throw decode_error("Invalid unicode"); 329 | } 330 | } 331 | break; 332 | default: 333 | throw decode_error("Unknown character entity"); 334 | } 335 | uint8_t buffer[4]; 336 | size_t len = encode_utf8(c, buffer); 337 | str.append((char *) buffer, len); 338 | } else if (is.eof()) { 339 | throw decode_error("Unexpected end of input"); 340 | } else if (c >= 0 && c <= 0x1F) { 341 | throw decode_error("Control character in a string"); 342 | } else { 343 | /* assume input is UTF-8 and pass through unmodified */ 344 | str += char(c); 345 | } 346 | c = is.get(); 347 | } 348 | return str; 349 | } 350 | 351 | void skip_string(std::istream &is) 352 | { 353 | int c = is.get(); 354 | while (c != '"') { 355 | if (c == '\\') { 356 | c = is.get(); 357 | if (is.eof()) { 358 | throw decode_error("Unexpected end of input"); 359 | } 360 | } else if (is.eof()) { 361 | throw decode_error("Unexpected end of input"); 362 | } else if (c >= 0 && c <= 0x1F) { 363 | throw decode_error("Control character in a string"); 364 | } 365 | c = is.get(); 366 | } 367 | } 368 | 369 | void encode_string(std::ostream &os, const std::string &str) 370 | { 371 | os.put('"'); 372 | for (size_t i = 0; i < str.size(); ++i) { 373 | int c = str[i]; 374 | switch (c) { 375 | case '\n': 376 | os.put('\\'); 377 | c = 'n'; 378 | break; 379 | case '\r': 380 | os.put('\\'); 381 | c = 'r'; 382 | break; 383 | case '\t': 384 | os.put('\\'); 385 | c = 't'; 386 | break; 387 | case '\f': 388 | os.put('\\'); 389 | c = 'f'; 390 | break; 391 | case '\b': 392 | os.put('\\'); 393 | c = 'b'; 394 | break; 395 | case '"': 396 | case '\\': 397 | os.put('\\'); 398 | break; 399 | default: 400 | break; 401 | } 402 | os.put(c); 403 | } 404 | os.put('"'); 405 | } 406 | 407 | void match(std::istream &is, const char *word, size_t len) 408 | { 409 | char buf[10]; 410 | is.read(buf, len); 411 | if (is.eof()) { 412 | throw decode_error("Unexpected end of input"); 413 | } 414 | if (memcmp(buf, word, len) != 0) { 415 | throw decode_error("Unknown keyword in input"); 416 | } 417 | 418 | int c = is.peek(); 419 | if (!is.eof() && (c >= 'a' && c <= 'z')) { 420 | throw decode_error("Unknown keyword in input"); 421 | } 422 | } 423 | 424 | /* Quickly skips an array (with less validation) */ 425 | void skip_array(std::istream &is) 426 | { 427 | int depth = 1; 428 | char dummy[10]; 429 | 430 | while (depth > 0) { 431 | skip_space(is); 432 | int c = is.get(); 433 | switch (c) { 434 | case '{': 435 | case '[': 436 | depth++; 437 | break; 438 | 439 | case '}': 440 | case ']': 441 | depth--; 442 | break; 443 | 444 | case ':': 445 | case ',': 446 | break; 447 | 448 | case '"': 449 | skip_string(is); 450 | break; 451 | 452 | case 't': 453 | /* true */ 454 | is.read(dummy, 3); 455 | if (is.eof()) { 456 | throw decode_error("Unexpected end of input"); 457 | } 458 | break; 459 | 460 | case 'f': 461 | /* false */ 462 | is.read(dummy, 4); 463 | if (is.eof()) { 464 | throw decode_error("Unexpected end of input"); 465 | } 466 | break; 467 | 468 | case 'n': 469 | /* null */ 470 | is.read(dummy, 3); 471 | if (is.eof()) { 472 | throw decode_error("Unexpected end of input"); 473 | } 474 | break; 475 | 476 | default: 477 | if ((c >= '0' && c <= '9') || c == '-') { 478 | /* Skip over a number */ 479 | c = is.peek(); 480 | while (!is.eof() && ((c >= '0' && c <= '9') || 481 | c == '.' || c == 'e' || 482 | c == '-' || c == '+')) { 483 | is.get(); 484 | c = is.peek(); 485 | } 486 | } else if (is.eof()) { 487 | throw decode_error("Unexpected end of input"); 488 | } else { 489 | throw decode_error("Unknown character in input"); 490 | } 491 | } 492 | } 493 | } 494 | 495 | Value Value::load_next(bool *end, bool lazy) 496 | { 497 | verify_type(JSON_LAZY_ARRAY); 498 | 499 | std::istream *is = m_value.lazy->is; 500 | /* 501 | * Avoid seek, because GNU libstdc++ discards the contents of internal 502 | * buffer when file pointer changes. 503 | */ 504 | if (m_value.lazy->offset != is->tellg()) { 505 | /* tellg() sets the stream state to bad. Clear it */ 506 | is->clear(); 507 | is->seekg(m_value.lazy->offset); 508 | } 509 | 510 | Value val; 511 | 512 | int c = skip_space(*is); 513 | if (c == ']') { 514 | /* End of the list, return null */ 515 | if (end != NULL) { 516 | *end = true; 517 | } 518 | } else { 519 | if (end != NULL) { 520 | *end = false; 521 | } 522 | val.load(*is, lazy); 523 | 524 | c = skip_space(*is); 525 | if (c == ',') { 526 | is->get(); 527 | } else if (c != ']') { 528 | throw decode_error("Expected ',' or ']'"); 529 | } 530 | } 531 | m_value.lazy->offset = is->tellg(); 532 | return val; 533 | } 534 | 535 | void Value::load(std::istream &is, bool lazy) 536 | { 537 | destroy(); 538 | 539 | /* 540 | * Note, we take adventage of the fact that when EOF is reached, 541 | * peek() and get() returns a special value that doesn't match 542 | * anything else. 543 | */ 544 | skip_space(is); 545 | int c = is.get(); 546 | switch (c) { 547 | case '{': 548 | m_type = JSON_OBJECT; 549 | m_value.object = new object_map_t; 550 | skip_space(is); 551 | c = is.get(); 552 | while (c != '}') { 553 | std::string key; 554 | if (c == '"') { 555 | key = load_string(is); 556 | } else if (is.eof()) { 557 | throw decode_error("Unexpected end of input"); 558 | } else { 559 | throw decode_error("Expected '}' or a string"); 560 | } 561 | skip_space(is); 562 | if (is.get() != ':') { 563 | throw decode_error("Expected ':'"); 564 | } 565 | /* 566 | * To avoid a copy, first insert an empty value to 567 | * the container and then load it from the input. 568 | */ 569 | std::pair res = 570 | m_value.object->insert(std::make_pair(key, Value())); 571 | if (!res.second) { 572 | throw decode_error("Duplicate key in object"); 573 | } 574 | res.first->second.load(is, lazy); 575 | 576 | c = skip_space(is); 577 | if (c == ',') { 578 | is.get(); 579 | skip_space(is); 580 | } else if (c != '}') { 581 | throw decode_error("Expected ',' or '}'"); 582 | } 583 | c = is.get(); 584 | } 585 | break; 586 | 587 | case '[': 588 | if (lazy) { 589 | m_type = JSON_LAZY_ARRAY; 590 | m_value.lazy = new LazyArray; 591 | m_value.lazy->is = &is; 592 | m_value.lazy->offset = is.tellg(); 593 | skip_array(is); 594 | } else { 595 | m_type = JSON_ARRAY; 596 | m_value.array = new std::vector; 597 | c = skip_space(is); 598 | while (c != ']') { 599 | m_value.array->push_back(Value()); 600 | m_value.array->back().load(is, lazy); 601 | 602 | c = skip_space(is); 603 | if (c == ',') { 604 | is.get(); 605 | c = skip_space(is); 606 | } else if (c != ']') { 607 | throw decode_error("Expected ',' or ']'"); 608 | } 609 | } 610 | is.get(); 611 | } 612 | break; 613 | 614 | case '"': 615 | m_value.string = new std::string(load_string(is)); 616 | m_type = JSON_STRING; 617 | break; 618 | 619 | case 't': 620 | match(is, "rue", 3); 621 | m_type = JSON_BOOLEAN; 622 | m_value.boolean = true; 623 | break; 624 | 625 | case 'f': 626 | match(is, "alse", 4); 627 | m_type = JSON_BOOLEAN; 628 | m_value.boolean = false; 629 | break; 630 | 631 | case 'n': 632 | match(is, "ull", 3); 633 | m_type = JSON_NULL; 634 | break; 635 | 636 | default: 637 | if ((c >= '0' && c <= '9') || c == '-') { 638 | /* 639 | * We need first to parse the number to a buffer to 640 | * decide if it's a float or an intger. 641 | */ 642 | bool is_float = false; 643 | std::string str; 644 | str += char(c); 645 | c = is.peek(); 646 | while (!is.eof() && ((c >= '0' && c <= '9') || 647 | c == '.' || c == 'e' || 648 | c == '-' || c == '+')) { 649 | if (c == '.' || c == 'e') { 650 | is_float = true; 651 | } 652 | str += char(c); 653 | is.get(); 654 | c = is.peek(); 655 | } 656 | std::istringstream parser(str); 657 | if (is_float) { 658 | m_type = JSON_FLOATING; 659 | parser >> m_value.floating; 660 | if (!parser) { 661 | throw decode_error("Invalid number"); 662 | } 663 | } else { 664 | m_type = JSON_INTEGER; 665 | parser >> m_value.integer; 666 | if (!parser) { 667 | throw decode_error("Invalid number"); 668 | } 669 | } 670 | parser.get(); 671 | if (!parser.eof()) { 672 | throw decode_error("Invalid number"); 673 | } 674 | } else if (is.eof()) { 675 | throw decode_error("Unexpected end of input"); 676 | } else { 677 | throw decode_error("Unknown character in input"); 678 | } 679 | } 680 | } 681 | 682 | void Value::load_all(std::istream &is, bool lazy) 683 | { 684 | load(is, lazy); 685 | skip_space(is); 686 | if (!is.eof()) { 687 | throw decode_error("Left over data in input"); 688 | } 689 | } 690 | 691 | void Value::write(std::ostream &os, int indent) const 692 | { 693 | static int depth = 0; 694 | 695 | switch (m_type) { 696 | case JSON_STRING: 697 | encode_string(os, *m_value.string); 698 | break; 699 | case JSON_OBJECT: 700 | os.put('{'); 701 | depth++; 702 | FOR_EACH_CONST(object_map_t, i, *m_value.object) { 703 | if (i != m_value.object->begin()) 704 | os << ", "; 705 | if (indent) { 706 | os.put('\n'); 707 | for (int n = 0; n < indent * depth; ++n) 708 | os.put(' '); 709 | } 710 | encode_string(os, i->first); 711 | os << ": "; 712 | i->second.write(os, indent); 713 | } 714 | depth--; 715 | if (indent) { 716 | os.put('\n'); 717 | for (int n = 0; n < indent * depth; ++n) 718 | os.put(' '); 719 | } 720 | os.put('}'); 721 | break; 722 | case JSON_ARRAY: 723 | os.put('['); 724 | FOR_EACH_CONST(std::vector, i, *m_value.array) { 725 | if (i != m_value.array->begin()) 726 | os << ", "; 727 | i->write(os, indent); 728 | } 729 | os.put(']'); 730 | break; 731 | case JSON_INTEGER: 732 | os << m_value.integer; 733 | break; 734 | case JSON_FLOATING: 735 | os << m_value.floating; 736 | break; 737 | case JSON_BOOLEAN: 738 | os << (m_value.boolean ? "true" : "false"); 739 | break; 740 | case JSON_NULL: 741 | os << "null"; 742 | break; 743 | default: 744 | assert(0); 745 | } 746 | } 747 | 748 | } 749 | -------------------------------------------------------------------------------- /src/scheduler/ThreadPool/Condition.cpp: -------------------------------------------------------------------------------- 1 | #include "Condition.h" 2 | 3 | /*craete Condition*/ 4 | Condition::Condition(CMutex &m) 5 | :_mutex(m) 6 | { 7 | pthread_cond_init(&_pcond, NULL); 8 | } 9 | /*destroy Condition*/ 10 | Condition::~Condition(){ 11 | pthread_cond_destroy(&_pcond); 12 | } 13 | /*wait Condition*/ 14 | void Condition::wait(){ 15 | pthread_cond_wait(&_pcond, _mutex.getThreadLock()); 16 | } 17 | /*awake threads*/ 18 | void Condition::notifyWake(){ 19 | pthread_cond_signal(&_pcond); 20 | } 21 | /*awake all the threads*/ 22 | void Condition::notifyWakeAll(){ 23 | pthread_cond_broadcast(&_pcond); 24 | } 25 | -------------------------------------------------------------------------------- /src/scheduler/ThreadPool/Condition.h: -------------------------------------------------------------------------------- 1 | #ifndef _CONDITION_H 2 | #define _CONDITION_H 3 | 4 | #include "head.h" 5 | #include "Mutex.h" 6 | #include 7 | using namespace std; 8 | /*Condition class*/ 9 | class Condition{ 10 | private: 11 | /*protected the Condition*/ 12 | CMutex &_mutex; 13 | pthread_cond_t _pcond; 14 | public: 15 | Condition(CMutex &m); 16 | ~Condition(); 17 | /*wait Condition*/ 18 | void wait(); 19 | /*awake thread*/ 20 | void notifyWake(); 21 | /*awake all the threads*/ 22 | void notifyWakeAll(); 23 | }; 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /src/scheduler/ThreadPool/Makefile: -------------------------------------------------------------------------------- 1 | main: main.o Threadpool.o Thread.o Condition.o Mutex.o head.h 2 | g++ -o main main.o Threadpool.o Thread.o Condition.o Mutex.o head.h -lpthread -std=c++11 3 | main.o: main.cpp Threadpool.cpp Threadpool.h Thread.cpp Thread.h Condition.cpp Condition.h Mutex.cpp Mutex.h head.h 4 | g++ -c main.cpp Threadpool.cpp Threadpool.h Thread.cpp Thread.h Condition.cpp Condition.h Mutex.cpp Mutex.h head.h -lpthread -std=c++11 5 | Threadpool.o: Threadpool.cpp Threadpool.h Thread.cpp Thread.h Condition.cpp Condition.h Mutex.cpp Mutex.h head.h 6 | g++ -c Threadpool.cpp Threadpool.h Thread.cpp Thread.h Condition.cpp Condition.h Mutex.cpp Mutex.h head.h -lpthread -std=c++11 7 | Thread.o: Thread.cpp Thread.h head.h 8 | g++ -c Thread.cpp Thread.h head.h -std=c++11 9 | Mutex.o: Mutex.cpp Mutex.h head.h 10 | g++ -c Mutex.cpp Mutex.h head.h -std=c++11 11 | Condition.o: Condition.cpp Mutex.cpp Condition.h Mutex.h head.h 12 | g++ -c Condition.cpp Condition.h Mutex.cpp Mutex.h head.h -std=c++11 13 | 14 | clean: 15 | rm -rf *.o 16 | rm -rf *.h.gch 17 | -------------------------------------------------------------------------------- /src/scheduler/ThreadPool/Mutex.cpp: -------------------------------------------------------------------------------- 1 | #include "Mutex.h" 2 | 3 | 4 | //CMutex code 5 | /********************************/ 6 | CMutex::CMutex() 7 | :_holder(0) 8 | { 9 | pthread_mutex_init(&_mutex, NULL); 10 | } 11 | 12 | CMutex::~CMutex(){ 13 | pthread_mutex_destroy(&_mutex); 14 | } 15 | /*lock the mutex*/ 16 | void CMutex::lock(){ 17 | pthread_mutex_lock(&_mutex); 18 | } 19 | /*unlock the mutex*/ 20 | void CMutex::unlock(){ 21 | pthread_mutex_unlock(&_mutex); 22 | } 23 | /*trylock*/ 24 | void CMutex::tryLock(){ 25 | pthread_mutex_trylock(&_mutex); 26 | } 27 | 28 | //void CMutex::assertLock(){ 29 | // assert(_holder == syscall(SYS_gettid)); 30 | //} 31 | 32 | /********************************/ 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /src/scheduler/ThreadPool/Mutex.h: -------------------------------------------------------------------------------- 1 | #ifndef _MUTEX_H 2 | #define _MUTEX_H 3 | 4 | #include "head.h" 5 | #include "Thread.h" 6 | #include 7 | #include 8 | using namespace std; 9 | 10 | /*pthread mutex class*/ 11 | class CMutex{ 12 | private: 13 | /*create mutex*/ 14 | pthread_mutex_t _mutex; 15 | /*the tid of thread*/ 16 | pid_t _holder; 17 | /*judge the mutex*/ 18 | bool islocked; 19 | public: 20 | /*create mutex class*/ 21 | CMutex(); 22 | ~CMutex(); 23 | /*lock the mutex*/ 24 | void lock(); 25 | /*unlock the mutex*/ 26 | void unlock(); 27 | /*trylock*/ 28 | void tryLock(); 29 | //void assertLock(); 30 | /*return mutex*/ 31 | pthread_mutex_t *getThreadLock(){ 32 | return &_mutex; 33 | } 34 | }; 35 | /*baled the mutex*/ 36 | class CMutexLock{ 37 | private: 38 | CMutex _mutex; 39 | public: 40 | explicit CMutexLock(CMutex &mutex) 41 | : _mutex(mutex) 42 | { 43 | _mutex.lock(); 44 | } 45 | ~CMutexLock(){ 46 | _mutex.unlock(); 47 | } 48 | }; 49 | 50 | #endif 51 | -------------------------------------------------------------------------------- /src/scheduler/ThreadPool/Thread.cpp: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | > File Name: Thread.cpp 3 | > Author: Darkfaker1024@163.com 4 | > Mail: Darkfaker 5 | > Created Time: Sat 21 Jul 2018 12:39:55 PM CST 6 | ************************************************************************/ 7 | 8 | #include "Thread.h" 9 | #include "Mutex.h" 10 | #include "Condition.h" 11 | #include 12 | using namespace std; 13 | 14 | //Thread cade 15 | //////////////////////////////////////////// 16 | 17 | Thread::Thread(ThreadFunc&& func, const string &n) 18 | : _isRuning(false) 19 | , _isJoined(false) 20 | , _pthreadId(0) 21 | , _tid(new pid_t(0)) 22 | , _func(move(func)) 23 | , _name(n) 24 | {} 25 | 26 | /*start a thread*/ 27 | void* runThread(void *msg){ 28 | ThreadData *data = static_cast(msg); 29 | /*call the thread func*/ 30 | data->runThreadFunc(); 31 | delete data; 32 | return NULL; 33 | } 34 | /*create a thread*/ 35 | void Thread::startThread(){ 36 | if (_isRuning) throw "start errror: is runging\n"; 37 | _isRuning = true; 38 | /*baled the thread data*/ 39 | ThreadData *data = new ThreadData(_func, _name, _tid); 40 | if (pthread_create(&_pthreadId, NULL, &runThread, (void*)data)){ 41 | _isRuning = false; 42 | delete data; 43 | } 44 | } 45 | /*merge the threads*/ 46 | int Thread::joinThread(){ 47 | if (!_isRuning) throw "join error: is not runing\n"; 48 | if (_isJoined) throw "join error: is joined\n"; 49 | _isJoined = true; 50 | return pthread_join(_pthreadId, NULL); 51 | } 52 | 53 | Thread::~Thread(){ 54 | if (_isRuning && !_isJoined) 55 | pthread_detach(_pthreadId); 56 | } 57 | //////////////////////////////////////////////// 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /src/scheduler/ThreadPool/Thread.h: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | > File Name: Thread.h 3 | > Author: Darkfaker1024@163.com 4 | > Mail: Darkfaker1024 5 | > Created Time: Fri 20 Jul 2018 05:15:41 PM CST 6 | ************************************************************************/ 7 | 8 | #ifndef _THREAD_H 9 | #define _THREAD_H 10 | #include "head.h" 11 | #include 12 | #include "Condition.h" 13 | #include "Mutex.h" 14 | #include 15 | #include 16 | using namespace std; 17 | 18 | /*id cache*/ 19 | class CacheTid{ 20 | public: 21 | pid_t _tid; 22 | CacheTid(pid_t i):_tid(i){} 23 | pid_t tid(){return static_cast(::syscall(SYS_gettid));} 24 | }; 25 | /*theads class*/ 26 | class Thread{ 27 | public: 28 | /*callback func*/ 29 | typedef function ThreadFunc; 30 | protected: 31 | bool _isRuning; 32 | bool _isJoined; 33 | /*thread id*/ 34 | pthread_t _pthreadId; 35 | /*smart ptr*/ 36 | shared_ptr _tid; 37 | /*callback func*/ 38 | ThreadFunc _func; 39 | /*threads name*/ 40 | string _name; 41 | public: 42 | explicit Thread(ThreadFunc&& func, const string &name = string()); 43 | ~Thread(); 44 | /*create a thread*/ 45 | void startThread(); 46 | /*merge the thread*/ 47 | int joinThread(); 48 | /*update tid*/ 49 | pid_t updateTid()const{return syscall(SYS_gettid);} 50 | /*get tid*/ 51 | pid_t getTid()const {return *_tid;} 52 | /*is runing*/ 53 | bool isStart()const {return _isRuning;} 54 | /*get name*/ 55 | const string &getName()const {return _name;} 56 | friend class ThreadData; 57 | 58 | }; 59 | 60 | /*baled the thread data*/ 61 | class ThreadData{ 62 | public: 63 | typedef Thread::ThreadFunc funcType; 64 | typedef shared_ptr _Ptr_Type; 65 | /*thread func*/ 66 | funcType _func; 67 | /*threads name*/ 68 | string _name; 69 | weak_ptr _wkTid; 70 | ThreadData(const funcType &func 71 | , const string &name 72 | , const shared_ptr &tid) 73 | : _func(func) 74 | , _name(name) 75 | , _wkTid(tid) 76 | {} 77 | /*use the smart ptr start thread func*/ 78 | void runThreadFunc(){ 79 | pthread_t tid = pthread_self(); 80 | _Ptr_Type ptid = _wkTid.lock(); 81 | if(ptid){ 82 | *ptid = tid; 83 | ptid.reset(); 84 | }/*try catch*/ 85 | try{ 86 | _func(); 87 | }catch(const string &str){ 88 | fprintf(stderr,"shared_ptr to wake_ptr error\n",_name.c_str()); 89 | cout << str << endl; 90 | abort(); 91 | }catch(const exception& ex){ 92 | fprintf(stderr,"shared_ptr to wake_ptr error\n",_name.c_str()); 93 | cout << ex.what() << endl; 94 | abort(); 95 | }catch(...){ 96 | fprintf(stderr,"unkown exception\n",_name.c_str()); 97 | abort(); 98 | throw; 99 | } 100 | } 101 | }; 102 | #endif 103 | -------------------------------------------------------------------------------- /src/scheduler/ThreadPool/Threadpool.cpp: -------------------------------------------------------------------------------- 1 | #include "Threadpool.h" 2 | #include "Thread.h" 3 | #include "Mutex.h" 4 | #include "Condition.h" 5 | #include 6 | #include 7 | #include 8 | 9 | /*construct*/ 10 | CThreadpool::CThreadpool(const string &n) 11 | : _mutex()/*init mutex*/ 12 | , _notFull(_mutex)/*init conditionn*/ 13 | , _notEmpty(_mutex)/*init condotion*/ 14 | , _poolName(n)/*init Threadpool name*/ 15 | , maxTaskQueSize(0)/*set task queu size*/ 16 | , isRuning(false)/*init false*/ 17 | {} 18 | /*init Threadpool*/ 19 | void CThreadpool::initPool(int numOfThread){ 20 | /*the number of Threads > 0*/ 21 | if (numOfThread <= 0) throw exception(); 22 | /*is runing*/ 23 | isRuning = true; 24 | /*reserve space*/ 25 | _threads.reserve(numOfThread); 26 | /*take the Threads to the vector*/ 27 | for (int i = 0; i < numOfThread; ++i){ 28 | char id[32]; 29 | snprintf(id, sizeof(id), "%d", i + 1); 30 | _threads.push_back( 31 | new Thread(bind(&CThreadpool::threadGetTask, this) 32 | , _poolName + id)); 33 | _threads[i]->startThread(); 34 | } 35 | if (numOfThread == 0 && _initCallBack){ 36 | _initCallBack(); 37 | } 38 | } 39 | /*run one thread,push one task*/ 40 | void CThreadpool::runThread(Construct_Task &&task){ 41 | /*if have only one thread*/ 42 | if (_threads.empty()){ 43 | task();/*run the task*/ 44 | } 45 | else{ 46 | /*locked*/ 47 | CMutexLock lock(_mutex); 48 | /*if task queue is full*/ 49 | while (isFull()){ 50 | /*wait task queue not full*/ 51 | _notFull.wait(); 52 | } 53 | assert(!isFull()); 54 | /*push one task*/ 55 | taskQue.push_back(move(task)); 56 | /*awake a thread*/ 57 | _notEmpty.notifyWake(); 58 | } 59 | } 60 | /*stop thread pool*/ 61 | void CThreadpool::stopPool(){ 62 | CMutexLock lock(_mutex); 63 | isRuning = false; 64 | /*awake all the threads*/ 65 | _notEmpty.notifyWakeAll(); 66 | /*join all the threads*/ 67 | for_each(_threads.begin(), _threads.end() 68 | , bind(&Thread::joinThread, placeholders::_1)); 69 | } 70 | 71 | void CThreadpool::setTaskQueSize(int s){ 72 | maxTaskQueSize = s; 73 | } 74 | 75 | void CThreadpool::setInitCallBack(const Construct_Task &c){ 76 | _initCallBack = c; 77 | } 78 | 79 | CThreadpool::~CThreadpool(){ 80 | if(isRuning){ 81 | stopPool(); 82 | } 83 | } 84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /src/scheduler/ThreadPool/Threadpool.h: -------------------------------------------------------------------------------- 1 | #ifndef _THREADPOOL_H 2 | #define _THREADPOOL_H 3 | 4 | #include 5 | #include "head.h" 6 | #include "Mutex.h" 7 | #include "Condition.h" 8 | #include "Thread.h" 9 | using namespace std; 10 | /*threadpool class*/ 11 | class CThreadpool{ 12 | public: 13 | typedef function Construct_Task; 14 | typedef vector Vec_Thread; 15 | typedef deque Task_Que; 16 | typedef unsigned int size_t; 17 | private: 18 | /*protected the Task_Que*/ 19 | CMutex _mutex; 20 | /*notice the threads*/ 21 | Condition _notFull; 22 | Condition _notEmpty; 23 | string _poolName; 24 | /*task callback func*/ 25 | Construct_Task _initCallBack; 26 | /*theads ptr*/ 27 | Vec_Thread _threads; 28 | /*task queue*/ 29 | Task_Que taskQue; 30 | size_t maxTaskQueSize; 31 | bool isRuning; 32 | bool isFull(){ 33 | // _mutex.assertLock(); 34 | return maxTaskQueSize > 0 && taskQue.size() >= maxTaskQueSize; 35 | } 36 | /*get task func*/ 37 | Construct_Task getTask(){ 38 | CMutexLock lock(_mutex); 39 | while(taskQue.empty() && isRuning){ 40 | _notEmpty.wait(); 41 | } 42 | Construct_Task task; 43 | if(!taskQue.empty()){ 44 | task = taskQue.front(); 45 | taskQue.pop_front(); 46 | if(maxTaskQueSize > 0){ 47 | _notFull.notifyWake(); 48 | } 49 | } 50 | return task; 51 | } 52 | 53 | /*take the task func from task queue*/ 54 | void threadGetTask(){ 55 | try{ 56 | if(_initCallBack){ 57 | cout << "threadGetTask()" << endl; 58 | _initCallBack(); 59 | } 60 | /*runing task*/ 61 | while(isRuning){ 62 | Construct_Task task(getTask()); 63 | if(task){ 64 | task(); 65 | } 66 | } 67 | /*try catch*/ 68 | }catch(const string &str){ 69 | fprintf(stderr,"callbackfunc error\n",_poolName.c_str()); 70 | abort(); 71 | }catch(const exception& ex){ 72 | fprintf(stderr,"callbackfunc error\n",_poolName.c_str()); 73 | cout << ex.what() << endl; 74 | abort(); 75 | }catch(...){ 76 | fprintf(stderr,"unknow exception\n",_poolName.c_str()); 77 | throw; 78 | } 79 | } 80 | /*take*/ 81 | 82 | public: 83 | CThreadpool(const string &n); 84 | /*start threadpool*/ 85 | void initPool(int numOfThread); 86 | /*stop threadpool*/ 87 | void stopPool(); 88 | /*run one thread*/ 89 | void runThread(Construct_Task &&task); 90 | void setTaskQueSize(int s); 91 | /*init callback*/ 92 | void setInitCallBack(const Construct_Task &c); 93 | ~CThreadpool(); 94 | }; 95 | 96 | #endif 97 | 98 | 99 | -------------------------------------------------------------------------------- /src/scheduler/ThreadPool/c.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | rm *.o 3 | rm *.h.gch 4 | #g++ -o main main.cpp Threadpool.cpp Thread.cpp Condition.cpp Mutex.cpp -std=c++11 -lpthread 5 | g++ -o main main.cpp Mutex.cpp Condition.cpp Thread.cpp Threadpool.cpp -lpthread -std=c++11 6 | -------------------------------------------------------------------------------- /src/scheduler/ThreadPool/head.h: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | > File Name: head.h 3 | > Author: Darkfaker 4 | > Mail: Darkfaker1024@163.com 5 | > Created Time: Wed 11 Jul 2018 04:00:58 PM CST 6 | ************************************************************************/ 7 | 8 | #ifndef _HEAD_H 9 | #define _HEAD_H 10 | /*c++*/ 11 | /********************/ 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | /*c*/ 26 | /*******************/ 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | 41 | 42 | #endif 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /src/scheduler/ThreadPool/main: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Darkfaker/filetransfer/8ba2bced677b43f0608aabbbfedbf12298bf5da5/src/scheduler/ThreadPool/main -------------------------------------------------------------------------------- /src/scheduler/ThreadPool/main.cpp: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | > File Name: main.cpp 3 | > Author: Darkfaker1024@163.com 4 | > Mail: 5 | > Created Time: Wed 25 Jul 2018 01:39:22 PM CST 6 | ************************************************************************/ 7 | 8 | #include 9 | #include "head.h" 10 | #include "Threadpool.h" 11 | #include "Thread.h" 12 | using namespace std; 13 | //class Threadpool; 14 | 15 | void func(){ 16 | cout << "thread 1 run" << endl; 17 | } 18 | 19 | void func2(){ 20 | cout << "thread 2 run" << endl; 21 | } 22 | 23 | int main(){ 24 | 25 | CThreadpool th(string("thread1")); 26 | th.setTaskQueSize(4); 27 | th.initPool(2); 28 | //th.setInitCallBack(func); 29 | th.runThread(func2); 30 | th.runThread(func); 31 | sleep(10); 32 | //th.runThread(func); 33 | return 0; 34 | } 35 | 36 | -------------------------------------------------------------------------------- /src/scheduler/dispatch/dispatch.cpp: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | > File Name: dispatch.cpp 3 | > Author: 4 | > Mail: 5 | > Created Time: Sat 28 Jul 2018 02:54:20 PM CST 6 | ************************************************************************/ 7 | 8 | #include 9 | using namespace std; 10 | 11 | -------------------------------------------------------------------------------- /src/scheduler/dispatch/dispatch.h: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | > File Name: dispatch.h 3 | > Author: 4 | > Mail: 5 | > Created Time: Sat 28 Jul 2018 02:54:15 PM CST 6 | ************************************************************************/ 7 | 8 | #ifndef _DISPATCH_H 9 | #define _DISPATCH_H 10 | #endif 11 | -------------------------------------------------------------------------------- /src/ser/include/LinuxFun.h: -------------------------------------------------------------------------------- 1 | #ifndef _LINUXFUN_H 2 | #define _LINUXFUN_H 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /src/ser/include/STL.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Darkfaker/filetransfer/8ba2bced677b43f0608aabbbfedbf12298bf5da5/src/ser/include/STL.h -------------------------------------------------------------------------------- /src/ser/main.cpp: -------------------------------------------------------------------------------- 1 | #include "FTP.h" 2 | #include "sockpair.h" 3 | #include "STL" 4 | #include "Dir.h" 5 | 6 | int main() 7 | { 8 | int sockfd = sockfd_init(); 9 | 10 | processpool *p1 = processpool::create(sockfd); 11 | p1->run(); 12 | 13 | return 0; 14 | } -------------------------------------------------------------------------------- /src/ser/process/Dir.h: -------------------------------------------------------------------------------- 1 | #ifndef _DIR_H 2 | #define _DIR_H 3 | 4 | #include "STL" 5 | using namespace std; 6 | typedef unsigned long long UNLL; 7 | 8 | /*dir informations*/ 9 | class CFileDirInfo{ 10 | public: 11 | CFileDirInfo(){} 12 | CFileDirInfo(bool is_file, string file_name, string md5) 13 | : _is_file(is_file) 14 | , _file_name(file_name) 15 | , _md5(md5){} 16 | 17 | CFileDirInfo& operator=(const CFileDirInfo &src){ 18 | _is_file = src._is_file; 19 | _file_name = src._file_name; 20 | return *this; 21 | } 22 | 23 | bool operator==(const CFileDirInfo &src){ 24 | return _file_name == src._file_name; 25 | } 26 | bool operator>(const CFileDirInfo &src){ 27 | return _file_name > src._file_name; 28 | } 29 | 30 | bool operator<(const CFileDirInfo &src){ 31 | return _file_name < src._file_name; 32 | } 33 | 34 | ~CFileDirInfo(){} 35 | bool _is_file; 36 | string _file_name; 37 | string _md5; 38 | }; 39 | 40 | /*file dir control*/ 41 | class CFileDir : public CFileDirInfo{ 42 | public: 43 | typedef list _ListType; 44 | CFileDir(string p, string Dir_name) 45 | : _Dir_name(Dir_name) 46 | , _pre_Dir(p) 47 | { 48 | _Dir_List = new _ListType; 49 | } 50 | 51 | void insert_file(const CFileDirInfo &m){ 52 | _Dir_List->push_front(m); 53 | } 54 | 55 | void del_file(const CFileDirInfo &m){ 56 | _ListType::iterator it = find(_Dir_List->begin(), _Dir_List->end(), m); 57 | _Dir_List->erase(it); 58 | } 59 | 60 | _ListType::iterator find_file(const CFileDirInfo &m){ 61 | return find(_Dir_List->begin(), _Dir_List->end(), m); 62 | } 63 | 64 | _ListType::iterator find_file(const string &m){ 65 | _ListType::iterator it = _Dir_List->begin(); 66 | for (; it != _Dir_List->end(); ++it){ 67 | if (it->_file_name == m) 68 | return it; 69 | } 70 | return _Dir_List->end(); 71 | } 72 | 73 | _ListType::iterator get_begin(){ 74 | return _Dir_List->begin(); 75 | } 76 | 77 | _ListType::iterator get_end(){ 78 | return _Dir_List->end(); 79 | } 80 | void show_File_Dir(); 81 | 82 | void show_Filr_Dir_All(); 83 | 84 | ~CFileDir(){} 85 | 86 | /*get*/ 87 | string &get_pre_dir(){ 88 | return _pre_Dir; 89 | } 90 | 91 | bool is_exist(const string &m){ 92 | return find_file(m) != _Dir_List->end(); 93 | } 94 | 95 | private: 96 | string _Dir_name; 97 | string _pre_Dir; 98 | list *_Dir_List; 99 | }; 100 | 101 | /*main dir control*/ 102 | class CDir{ 103 | public: 104 | typedef unordered_map _MapType; 105 | static CDir *GetDirMap(){ return &_CDir; } 106 | ~CDir(){} 107 | 108 | void insert_dir(const string &m, const CFileDir &f){ 109 | _Dir_map.insert(make_pair(m, f)); 110 | } 111 | 112 | void del_dir(const string &m){ 113 | _Dir_map.erase(m); 114 | } 115 | 116 | _MapType::iterator find_dir(const string &m){ 117 | return _Dir_map.find(m); 118 | } 119 | 120 | CFileDir::_ListType::iterator find_all(const string &m){ 121 | _MapType::iterator it = _Dir_map.begin(); 122 | 123 | for (; it != _Dir_map.end(); ++it){ 124 | CFileDir::_ListType::iterator fileit = it->second.find_file(m); 125 | if (fileit != it->second.get_end()) 126 | return fileit; 127 | 128 | } 129 | return find_dir(_while_Dir)->second.get_end(); 130 | } 131 | 132 | CFileDir::_ListType::iterator get_file_end(){ 133 | return find_dir(_while_Dir)->second.get_end(); 134 | } 135 | 136 | _MapType::iterator get_begin(){ 137 | return _Dir_map.begin(); 138 | } 139 | 140 | _MapType::iterator get_end(){ 141 | return _Dir_map.end(); 142 | } 143 | void show_Dir(const string &m); 144 | 145 | void show_Dir_All(); 146 | 147 | string &whilch_dir(){ 148 | return _while_Dir; 149 | } 150 | 151 | void change_dir(const char *m){ 152 | _while_Dir.replace(_while_Dir.begin() 153 | , _while_Dir.end(), m); 154 | } 155 | 156 | private: 157 | string _while_Dir; 158 | UNLL _Dir_count; 159 | unordered_map _Dir_map; 160 | static CDir _CDir; 161 | CDir(string _pre_Dir) 162 | : _Dir_count(1), _while_Dir("ftpser"){} 163 | }; 164 | CDir CDir::_CDir; 165 | 166 | inline void CFileDir::show_File_Dir(){ 167 | _ListType::iterator it = _Dir_List->begin(); 168 | int i = 0; 169 | 170 | for (; it != _Dir_List->end(); ++it){ 171 | cout << "dir:>>" << endl; 172 | if (!it->_is_file){ 173 | if (i++ == 5) 174 | cout << endl; 175 | cout << it->_file_name << " "; 176 | } 177 | } 178 | 179 | for (it = _Dir_List->begin(); it != _Dir_List->end(); ++it){ 180 | cout << "dir:>>" << endl; 181 | if (it->_is_file){ 182 | if (i++ == 5) 183 | cout << endl; 184 | cout << it->_file_name << " "; 185 | } 186 | } 187 | cout << endl; 188 | } 189 | 190 | /*dir show*/ 191 | inline void CDir::show_Dir(const string &m){ 192 | _MapType::iterator it = _Dir_map.find(m); 193 | if (it == _Dir_map.end()) 194 | throw "not find this Dir!"; 195 | it->second.show_File_Dir(); 196 | } 197 | 198 | inline void CDir::show_Dir_All(){ 199 | _MapType::iterator it = _Dir_map.begin(); 200 | cout << "- " << it->first << "----" << endl; 201 | for (; it != _Dir_map.end(); ++it){ 202 | it->second.show_Filr_Dir_All(); 203 | it->second.show_File_Dir(); 204 | } 205 | } 206 | 207 | #endif 208 | 209 | -------------------------------------------------------------------------------- /src/ser/process/FTP.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Darkfaker/filetransfer/8ba2bced677b43f0608aabbbfedbf12298bf5da5/src/ser/process/FTP.h -------------------------------------------------------------------------------- /src/ser/process/process.cpp: -------------------------------------------------------------------------------- 1 | #include "FTP.h" 2 | #include "sockpair.h" 3 | #include "STL" 4 | #include "Dir.h" 5 | #include "LinuxFun.h" 6 | #include 7 | using namespace std; 8 | typedef unsigned long long UNLL; 9 | 10 | void send_file(int, int, int); 11 | void recv_file(int, int, int); 12 | 13 | const int B_SIZE = 1024; 14 | //fork control 15 | class ForkExecv{ 16 | public: 17 | ForkExecv(){} 18 | ~ForkExecv(){} 19 | /*fork sockpair control*/ 20 | string Fork_pro_comd(string comd){ 21 | char buff[B_SIZE]; 22 | string tmpbuff; 23 | FILE *fp; 24 | fp = dpopen(comd.c_str()); 25 | if (fp == NULL){ 26 | perror("dpopen error"); 27 | exit(1); 28 | } 29 | if (dphalfclose(fp) < 0){ 30 | perror("dphalfclose error"); 31 | exit(1); 32 | } 33 | while (1){ 34 | if (fgets(buff, B_SIZE, fp) == NULL) 35 | break; 36 | tmpbuff += buff; 37 | } 38 | return string(tmpbuff); 39 | dpclose(fp); 40 | } 41 | private: 42 | }; 43 | 44 | //file control class 45 | class CFile{ 46 | public: 47 | typedef list _Mytype; 48 | CFile(){} 49 | CFile(string file_name) 50 | : _file_name(file_name) 51 | , _link_count(0) 52 | { 53 | _file_list = new _Mytype; 54 | } 55 | // find file 56 | bool find_file(const string &file_name) 57 | { 58 | _Mytype::iterator it = find(_file_list->begin(), _file_list->end(), file_name); 59 | return it != _file_list->end(); 60 | } 61 | // insert file 62 | void insert_file(const string &file_name){ 63 | _file_list->push_front(file_name); 64 | ++_link_count; 65 | } 66 | //del file 67 | void del_file(const string &file_name){ 68 | _Mytype::iterator it = find(_file_list->begin(), _file_list->end(), file_name); 69 | _file_list->erase(it); 70 | --_link_count; 71 | } 72 | 73 | string _file_name; 74 | list *_file_list; 75 | UNLL _link_count; 76 | }; 77 | 78 | //MD5 control class 79 | class CMd5 : public ForkExecv{ 80 | public: 81 | typedef unordered_map _Mytype; 82 | 83 | static CMd5 *GetMd5(){ return &_md5; } 84 | ~CMd5(){} 85 | string make_md5(const string &file_name){ 86 | _comd += file_name; 87 | _md5_Str = ForkExecv::Fork_pro_comd(_comd); 88 | } 89 | //insert md5 90 | void insert_md5(const string &m, const CFile &file){ 91 | _Md5_map.insert(make_pair(m, file)); 92 | } 93 | //del md5 94 | void del_md5(const string &m){ 95 | _Md5_map.erase(m); 96 | } 97 | //find md5 98 | _Mytype::iterator find_md5(const string &m){ 99 | return _Md5_map.find(m); 100 | } 101 | //get end 102 | _Mytype::iterator get_end(){ 103 | return _Md5_map.end(); 104 | } 105 | //get begin 106 | _Mytype::iterator get_begin(){ 107 | return _Md5_map.begin(); 108 | } 109 | private: 110 | unordered_map _Md5_map; 111 | CMd5() :_comd("md5sum"){}; 112 | string _comd; 113 | static CMd5 _md5; 114 | string _md5_Str; 115 | }; 116 | CMd5 CMd5::_md5; 117 | 118 | /*cli clasa control*/ 119 | class CProecss : public ForkExecv, public CFile{ 120 | public: 121 | typedef typename CMd5::_Mytype _MapType; 122 | CProecss(){ 123 | _md5 = CMd5::GetMd5(); 124 | _Dir = CDir::GetDirMap(); 125 | } 126 | void init(int epollfd, int sockfd, struct sockaddr_in addr){ 127 | _sockfd = sockfd; 128 | } 129 | void process(); 130 | 131 | void Put_Ctl(char **myargv); 132 | 133 | void Get_Ctl(char **myargv); 134 | 135 | void Dir_Ctl(char **myargv); 136 | 137 | void Dir_file_Add(char **myargv, bool isfile = true); 138 | 139 | void show_ctl(char **myargv, bool isall = false); 140 | 141 | void Dir_Add(char **myargv); 142 | private: 143 | string _comd;//cmd 144 | string _file_name;//file 145 | int _port_addr;//addr 146 | int _sockfd; 147 | CMd5 *_md5; 148 | string _md5_str; 149 | bool _need_put; 150 | CDir *_Dir; 151 | }; 152 | 153 | /*main loop*/ 154 | void CProecss::process(){ 155 | cout << "run >> " << endl; 156 | char *myargv[10]; 157 | char *comd = new char[128](); 158 | recv(_sockfd, comd, 128, 0); 159 | char *p = strtok(comd, " "); 160 | 161 | myargv[0] = p; 162 | int i = 0; 163 | while (NULL != (p = strtok(NULL, " "))) 164 | myargv[++i] = p; 165 | strcpy(comd, myargv[0]); 166 | 167 | _comd = comd; 168 | string path("/bin/"); 169 | string cmd(myargv[0]); 170 | if (cmd == "get"){ 171 | Get_Ctl(myargv); 172 | return; 173 | } 174 | else if (cmd == "put"){ 175 | Put_Ctl(myargv); 176 | Dir_file_Add(myargv); 177 | return; 178 | } 179 | else if (cmd == "cd"){ 180 | Dir_Ctl(myargv); 181 | return; 182 | } 183 | else if (cmd == "cp") 184 | return; 185 | else if (cmd == "ls") 186 | Dir_Ctl(myargv); 187 | else if (cmd == "mkdir") 188 | Dir_file_Add(myargv, false); 189 | else{ 190 | string recv_buff = ForkExecv::Fork_pro_comd(_comd); 191 | send(_sockfd, recv_buff.c_str(), recv_buff.length(), 0); 192 | return; 193 | } 194 | } 195 | 196 | /*put file control*/ 197 | inline void CProecss::Put_Ctl(char **myargv){ 198 | _MapType::iterator it = _md5->find_md5(string(myargv[2])); 199 | 200 | if (it == _md5->get_end()){ 201 | int fw = open(myargv[1], O_WRONLY | O_CREAT, 0600); 202 | if (fw == -1) 203 | return; 204 | int file_size; 205 | sscanf(myargv[3], "%d", &file_size); 206 | CFile file = CFile(string(myargv[1])); 207 | file.insert_file(string(myargv[1])); 208 | _md5->insert_md5(string(myargv[2]), file); 209 | recv_file(_sockfd, file_size, fw); 210 | } 211 | else{ 212 | it->second.insert_file(string(myargv[1])); 213 | send(_sockfd, "no", 2, 0); 214 | cout << "we have this file ......." << endl; 215 | } 216 | } 217 | 218 | /*get file control*/ 219 | inline void CProecss::Get_Ctl(char **myargv){ 220 | _MapType::iterator it = _md5->find_md5(string(myargv[1])); 221 | if (it != _md5->get_end()) 222 | send(_sockfd, "no file", 7, 0); 223 | else{ 224 | cout << "open file " << endl; 225 | int fd = open(myargv[1], O_RDONLY); 226 | if (fd == -1){ 227 | cout << "------have no file!----" << endl; 228 | return; 229 | } 230 | int size = lseek(fd, 0, SEEK_END); 231 | lseek(fd, 0, SEEK_SET); 232 | char buff[32] = { 0 }; 233 | sprintf(buff, "%d", size); 234 | cout << "buff :" << endl; 235 | send(_sockfd, buff, 32, 0); 236 | send_file(_sockfd, fd, size); 237 | } 238 | } 239 | 240 | int sockfd_init(){ 241 | int sockfd = socket(AF_INET, SOCK_STREAM, 0); 242 | assert(sockfd != -1); 243 | struct sockaddr_in saddr; 244 | memset(&saddr, 0, sizeof(saddr)); 245 | saddr.sin_family = AF_INET; 246 | saddr.sin_port = htons(6000); 247 | saddr.sin_addr.s_addr = inet_addr("127.0.0.1"); 248 | 249 | int res = bind(sockfd, (struct sockaddr*)&saddr, sizeof(saddr)); 250 | 251 | listen(sockfd, 5); 252 | return sockfd; 253 | } 254 | 255 | typedef unsigned long long UNLL; 256 | /*reve file control*/ 257 | inline void recv_file(int sockfd, int file_size, int fw){ 258 | cout << "-------put file......-------" << endl; 259 | cout << "file_size:" << file_size << endl; 260 | send(sockfd, "ok", 2, 0); 261 | int fin_size(0); 262 | int numb(0); 263 | char *recv_buff = new char[1024](); 264 | 265 | while ((numb = recv(sockfd, recv_buff, 1024, 0)) > 0){ 266 | fin_size += numb; 267 | write(fw, recv_buff, numb); 268 | memset(recv_buff, 0, 1024); 269 | if (fin_size == file_size) 270 | break; 271 | } 272 | 273 | cout << "-------put finsh!-------" << endl; 274 | 275 | delete[]recv_buff; 276 | close(fw); 277 | } 278 | 279 | /*send file control*/ 280 | inline void send_file(int sockfd, int fd, int file_size){ 281 | cout << "send_file......." << endl; 282 | char buff[2]; 283 | recv(sockfd, buff, 2, 0); 284 | sendfile(sockfd, fd, NULL, file_size); 285 | cout << "send_file fin!" << endl; 286 | close(fd); 287 | } 288 | 289 | /*Dir control loop*/ 290 | inline void CProecss::Dir_Ctl(char **myargv){ 291 | string w_dir = _Dir->whilch_dir(); 292 | CDir::_MapType::iterator mapit = _Dir->find_dir(w_dir); 293 | string dir(myargv[1]); 294 | if (dir == "."){ 295 | _Dir->change_dir(myargv[1]); 296 | _Dir->show_Dir(string(myargv[1])); 297 | } 298 | else if (dir == ".."){ 299 | _Dir->change_dir(mapit->second.get_pre_dir().c_str()); 300 | _Dir->show_Dir(string(myargv[1])); 301 | } 302 | else if (dir[0] == (char)"/"){ 303 | char *dir[10] = { 0 }; 304 | char *p = strtok(myargv[1], "/"); 305 | if (NULL == p) 306 | return; 307 | dir[0] = p; 308 | int i = 0; 309 | while (NULL != (p = strtok(NULL, " "))) 310 | dir[++i] = p; 311 | CFileDir::_ListType::iterator it; 312 | CDir::_MapType::iterator it2; 313 | for (int j = 0; j < i; ++j){ 314 | it2 = _Dir->find_dir(string(dir[j])); 315 | if (it2 == _Dir->get_end()){ 316 | string buff("this is a file, not a dir!"); 317 | cout << buff << endl; 318 | return; 319 | } 320 | } 321 | _Dir->change_dir(dir[i - 1]); 322 | } 323 | else{ 324 | _Dir->change_dir(myargv[1]); 325 | _Dir->show_Dir(string(myargv[1])); 326 | } 327 | } 328 | 329 | /*dir file add control*/ 330 | inline void CProecss::Dir_file_Add(char **myargv, bool isfile = true){ 331 | string w_dir = _Dir->whilch_dir(); 332 | CDir::_MapType::iterator mapit = _Dir->find_dir(w_dir); 333 | 334 | if (mapit == _Dir->get_end()){ 335 | cout << "not find this Dir!" << endl; 336 | throw "not find this Dir!"; 337 | } 338 | else{ 339 | CFileDirInfo fileinfo(isfile, string(myargv[1]), string(myargv[2])); 340 | CFileDir::_ListType::iterator fileit = mapit->second.find_file(fileinfo); 341 | if (fileit == mapit->second.get_end()){ 342 | if (isfile) 343 | mapit->second.insert_file(fileinfo); 344 | else 345 | _Dir->insert_dir(string(myargv[1]), CFileDir(w_dir, string(myargv[1]))); 346 | } 347 | else{ 348 | string buff("There is one file have the same name!"); 349 | cout << buff << endl; 350 | //send(); 351 | } 352 | } 353 | } 354 | 355 | inline void CProecss::show_ctl(char **myargv, bool isall = false){ 356 | string cmd(myargv[1]); 357 | 358 | _Dir->show_Dir_All(); 359 | } 360 | --------------------------------------------------------------------------------