├── CloudPan1.0 ├── Makefile ├── client │ ├── MCache.h │ ├── Makefile │ ├── cli │ ├── conCli.cpp │ ├── conCli.h │ ├── login.h │ ├── md5.cpp │ └── md5.h ├── public.h ├── readme.md ├── server │ ├── FTS │ ├── FTSLog.out │ ├── Makefile │ ├── MyDB.cpp │ ├── MyDB.h │ ├── chart.cpp │ ├── chart.h │ ├── conSer.cpp │ ├── conSer.h │ ├── fileTrans.cpp │ ├── fileTrans.h │ ├── main │ ├── main.cpp │ ├── md5.cpp │ ├── md5.h │ ├── ser │ ├── serLog.out │ ├── sqlConnPool.cpp │ ├── sqlConnPool.h │ ├── tPool.cpp │ ├── tPool.h │ └── testser.cpp └── test │ ├── mysql.cpp │ └── xcp.c └── README.md /CloudPan1.0/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY:clean all 2 | exec: 3 | #g++ -c md5.cpp; 4 | #ar -rc md5.a md5.o; 5 | #g++ -c MyDB.cpp; 6 | #ar -rc MyDB.a MyDB.o; 7 | 8 | #g++ -o cli conCli.cpp md5.a; 9 | #g++ -o cli testcli.cpp conCli.a md5.a; 10 | #g++ -o ser conSer.cpp MyDB.a -L/usr/lib/mysql -lmysqlclient --std=c++0x; 11 | 12 | g++ -o cli conCli.cpp md5.cpp 13 | g++ -o ser conSer.cpp MyDB.cpp -I /usr/include/libmemcached/include -L/usr/include/libmemcached/lib -L/usr/lib/mysql -lmysqlclient -lmemcached -lpthread --std=gnu++0x; 14 | g++ -o FTS fileTrans.cpp md5.cpp MyDB.cpp -I /usr/include/libmemcached/include -L/usr/include/libmemcached/lib -L/usr/lib/mysql -lmysqlclient -lmemcached -lpthread --std=gnu++0x; 15 | clean: 16 | rm -f *.o; 17 | rm -f *~; 18 | rm *.a; 19 | 20 | 21 | -------------------------------------------------------------------------------- /CloudPan1.0/client/MCache.h: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | > File Name: MCache.h 3 | > Author: qinyu 4 | > Mail: qinyu.LT@gmail.com 5 | > Created Time: 2016年05月19日 星期四 20时12分57秒 6 | ************************************************************************/ 7 | #ifndef _MCACHED_H 8 | #define _MCACHED_H 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | using namespace std; 15 | 16 | class MCache 17 | { 18 | public: 19 | MCache(const char *ip,int port) 20 | { 21 | memc = memcached_create(NULL); 22 | servers = memcached_server_list_append(NULL,ip,port,&rc); 23 | rc = memcached_server_push(memc,servers); 24 | memcached_server_free(servers); 25 | } 26 | ~MCache() 27 | { 28 | memcached_free(memc); 29 | } 30 | bool insertValue(const char *key,const char *value,int timeout) 31 | { 32 | rc = memcached_set(memc,key,strlen(key),value,strlen(value),(time_t)timeout,(uint32_t)0); 33 | if(rc == MEMCACHED_SUCCESS) 34 | { 35 | cout<<"Save key: "< File Name: conCli.cpp 3 | > Author: qinyu 4 | > Mail: qinyu.LT@gmail.com 5 | > Created Time: 2016年04月19日 星期二 22时48分39秒 6 | ************************************************************************/ 7 | #include "md5.h" 8 | #include "conCli.h" 9 | 10 | conCli::conCli(int port,const char *addr) 11 | { 12 | m_addr = addr; 13 | if((sock=socket(PF_INET,SOCK_STREAM,0)) < 0) 14 | ERR_EXIT("socket"); 15 | memset(&seraddr,0,sizeof(seraddr)); 16 | seraddr.sin_family = AF_INET; 17 | seraddr.sin_port = htons(port); 18 | seraddr.sin_addr.s_addr = inet_addr(m_addr);//htonl(INADDR_ANY); 19 | //cout<<"conCli successful!"<: "; 46 | } 47 | 48 | void conCli::function() 49 | { 50 | system("clear"); 51 | cout<<"===================================="<: "; 59 | } 60 | 61 | void conCli::sendmsg() 62 | { 63 | while(1) 64 | { 65 | int res = send(sock,(msg.c_str()),msg.size()+1,0); 66 | //cout<<"res = "<>user; 94 | msg += user; 95 | cout<<"密 码:"; 96 | cin>>passwd; 97 | //msg = msg + " "+passwd; 98 | msg = msg + " " +MD5(passwd).toString(); 99 | //cout<<"send msg = "<>select; 109 | 110 | switch(select) 111 | { 112 | case ENTER://登录 113 | msg = "1 "; 114 | getinfor(); 115 | break; 116 | 117 | case REGISTER://注册 118 | msg = "2 "; 119 | getinfor(); 120 | break; 121 | 122 | case CHART://聊天 123 | msg = "5 "; 124 | break; 125 | 126 | case UPLODE://上传文件 127 | msg = "3 "; 128 | break; 129 | 130 | case DOWNLOAD://下载文件 131 | msg = "4 "; 132 | break; 133 | 134 | default: 135 | msg = "-1 "; 136 | break; 137 | } 138 | } 139 | 140 | int main() 141 | { 142 | conCli cli(CPT,"127.0.0.1"); 143 | cli.Run(); 144 | return 0; 145 | } 146 | -------------------------------------------------------------------------------- /CloudPan1.0/client/conCli.h: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | > File Name: conCli.h 3 | > Author: qinyu 4 | > Mail: qinyu.LT@gmail.com 5 | > Created Time: 2016年04月19日 星期二 22时50分11秒 6 | ************************************************************************/ 7 | 8 | #ifndef CONCLI_H 9 | #define CONCLI_H 10 | #include "../public.h" 11 | 12 | class conCli 13 | { 14 | public: 15 | conCli(int port,const char *addr); 16 | ~conCli(); 17 | void Run(); 18 | void wellcome(); 19 | void function(); 20 | void do_work(); 21 | void sendmsg(); 22 | void getinfor(); 23 | private: 24 | int sock; 25 | //int trans_fd; 26 | //int check_fd; 27 | int port; 28 | const char *m_addr; 29 | //msgInfo msg; 30 | string msg; 31 | //list msg; 32 | //list::iterator it; 33 | struct sockaddr_in seraddr; 34 | }; 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /CloudPan1.0/client/login.h: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | > File Name: login.h 3 | > Author: qinyu 4 | > Mail: qinyu.LT@gmail.com 5 | > Created Time: 2016年04月19日 星期二 22时55分11秒 6 | ************************************************************************/ 7 | #ifndef LOGIN_H 8 | #define LOGIN_H 9 | 10 | list msg; 11 | string user; 12 | string passwd; 13 | 14 | enum OP_TYPE{ENTER=1,REGISTER=2,UPLODE=3,DOWNLOAD=4,CHAT=5}; 15 | 16 | void wellcome() 17 | { 18 | cout<<"===================================="<>select; 46 | switch(select) 47 | { 48 | case ENTER: 49 | cout<<"用户名:"; 50 | cin>>user; 51 | cout<<"密 码:"; 52 | cin>>paaword; 53 | msg.push_back("ENTER"); 54 | msg.push_back(user); 55 | msg.push_back(passwd); 56 | 57 | send(); 58 | break; 59 | 60 | case REGISTER: 61 | cout<<"用户名:"; 62 | cin>>user; 63 | cout<<"密 码:"; 64 | cin>>paaword; 65 | msg.push_back("REGISTER"); 66 | msg.push_back(user); 67 | msg.push_back(passwd); 68 | 69 | send(); 70 | break; 71 | 72 | case CHAT: 73 | break; 74 | 75 | case UPLODE: 76 | break; 77 | 78 | case DOWNLOAD: 79 | break; 80 | 81 | default: 82 | break; 83 | } 84 | } 85 | 86 | #endif 87 | -------------------------------------------------------------------------------- /CloudPan1.0/client/md5.cpp: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | > File Name: md5.cpp 3 | > Author: qinyu 4 | > Mail: qinyu.LT@gmail.com 5 | > Created Time: 2016年04月21日 星期四 23时21分59秒 6 | ************************************************************************/ 7 | #include "md5.h" 8 | #include "../public.h" 9 | using namespace std; 10 | 11 | /* Constants for MD5Transform routine. */ 12 | #define S11 7 13 | #define S12 12 14 | #define S13 17 15 | #define S14 22 16 | #define S21 5 17 | #define S22 9 18 | #define S23 14 19 | #define S24 20 20 | #define S31 4 21 | #define S32 11 22 | #define S33 16 23 | #define S34 23 24 | #define S41 6 25 | #define S42 10 26 | #define S43 15 27 | #define S44 21 28 | 29 | 30 | /* F, G, H and I are basic MD5 functions. 31 | */ 32 | #define F(x, y, z) (((x) & (y)) | ((~x) & (z))) 33 | #define G(x, y, z) (((x) & (z)) | ((y) & (~z))) 34 | #define H(x, y, z) ((x) ^ (y) ^ (z)) 35 | #define I(x, y, z) ((y) ^ ((x) | (~z))) 36 | 37 | /* ROTATE_LEFT rotates x left n bits. 38 | */ 39 | #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) 40 | 41 | /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. 42 | Rotation is separate from addition to prevent recomputation. 43 | */ 44 | #define FF(a, b, c, d, x, s, ac) { \ 45 | (a) += F ((b), (c), (d)) + (x) + ac; \ 46 | (a) = ROTATE_LEFT ((a), (s)); \ 47 | (a) += (b); \ 48 | } 49 | #define GG(a, b, c, d, x, s, ac) { \ 50 | (a) += G ((b), (c), (d)) + (x) + ac; \ 51 | (a) = ROTATE_LEFT ((a), (s)); \ 52 | (a) += (b); \ 53 | } 54 | #define HH(a, b, c, d, x, s, ac) { \ 55 | (a) += H ((b), (c), (d)) + (x) + ac; \ 56 | (a) = ROTATE_LEFT ((a), (s)); \ 57 | (a) += (b); \ 58 | } 59 | #define II(a, b, c, d, x, s, ac) { \ 60 | (a) += I ((b), (c), (d)) + (x) + ac; \ 61 | (a) = ROTATE_LEFT ((a), (s)); \ 62 | (a) += (b); \ 63 | } 64 | 65 | 66 | const byte MD5::PADDING[64] = { 0x80 }; 67 | const char MD5::HEX[16] = { 68 | '0', '1', '2', '3', 69 | '4', '5', '6', '7', 70 | '8', '9', 'a', 'b', 71 | 'c', 'd', 'e', 'f' 72 | }; 73 | 74 | 75 | /* Default construct. */ 76 | MD5::MD5() { 77 | reset(); 78 | } 79 | 80 | /* Construct a MD5 object with a input buffer. */ 81 | MD5::MD5(const void* input, size_t length) { 82 | reset(); 83 | update(input, length); 84 | } 85 | 86 | /* Construct a MD5 object with a string. */ 87 | MD5::MD5(const string& str) { 88 | reset(); 89 | update(str); 90 | } 91 | 92 | /* Construct a MD5 object with a file. */ 93 | MD5::MD5(ifstream& in) { 94 | reset(); 95 | update(in); 96 | } 97 | 98 | /* Return the message-digest */ 99 | const byte* MD5::digest() { 100 | 101 | if (!_finished) { 102 | _finished = true; 103 | final(); 104 | } 105 | return _digest; 106 | } 107 | 108 | /* Reset the calculate state */ 109 | void MD5::reset() { 110 | 111 | _finished = false; 112 | /* reset number of bits. */ 113 | _count[0] = _count[1] = 0; 114 | /* Load magic initialization constants. */ 115 | _state[0] = 0x67452301; 116 | _state[1] = 0xefcdab89; 117 | _state[2] = 0x98badcfe; 118 | _state[3] = 0x10325476; 119 | } 120 | 121 | /* Updating the context with a input buffer. */ 122 | void MD5::update(const void* input, size_t length) { 123 | update((const byte*)input, length); 124 | } 125 | 126 | /* Updating the context with a string. */ 127 | void MD5::update(const string& str) { 128 | update((const byte*)str.c_str(), str.length()); 129 | } 130 | 131 | /* Updating the context with a file. */ 132 | void MD5::update(ifstream& in) { 133 | 134 | if (!in) { 135 | return; 136 | } 137 | 138 | std::streamsize length; 139 | char buffer[BUFFER_SIZE]; 140 | while (!in.eof()) { 141 | in.read(buffer, BUFFER_SIZE); 142 | length = in.gcount(); 143 | if (length > 0) { 144 | update(buffer, length); 145 | } 146 | } 147 | in.close(); 148 | } 149 | 150 | /* MD5 block update operation. Continues an MD5 message-digest 151 | operation, processing another message block, and updating the 152 | context. 153 | */ 154 | void MD5::update(const byte* input, size_t length) { 155 | 156 | uint32 i, index, partLen; 157 | 158 | _finished = false; 159 | 160 | /* Compute number of bytes mod 64 */ 161 | index = (uint32)((_count[0] >> 3) & 0x3f); 162 | 163 | /* update number of bits */ 164 | if ((_count[0] += ((uint32)length << 3)) < ((uint32)length << 3)) { 165 | ++_count[1]; 166 | } 167 | _count[1] += ((uint32)length >> 29); 168 | 169 | partLen = 64 - index; 170 | 171 | /* transform as many times as possible. */ 172 | if (length >= partLen) { 173 | 174 | memcpy(&_buffer[index], input, partLen); 175 | transform(_buffer); 176 | 177 | for (i = partLen; i + 63 < length; i += 64) { 178 | transform(&input[i]); 179 | } 180 | index = 0; 181 | 182 | } else { 183 | i = 0; 184 | } 185 | 186 | /* Buffer remaining input */ 187 | memcpy(&_buffer[index], &input[i], length - i); 188 | } 189 | 190 | /* MD5 finalization. Ends an MD5 message-_digest operation, writing the 191 | the message _digest and zeroizing the context. 192 | */ 193 | void MD5::final() { 194 | 195 | byte bits[8]; 196 | uint32 oldState[4]; 197 | uint32 oldCount[2]; 198 | uint32 index, padLen; 199 | 200 | /* Save current state and count. */ 201 | memcpy(oldState, _state, 16); 202 | memcpy(oldCount, _count, 8); 203 | 204 | /* Save number of bits */ 205 | encode(_count, bits, 8); 206 | 207 | /* Pad out to 56 mod 64. */ 208 | index = (uint32)((_count[0] >> 3) & 0x3f); 209 | padLen = (index < 56) ? (56 - index) : (120 - index); 210 | update(PADDING, padLen); 211 | 212 | /* Append length (before padding) */ 213 | update(bits, 8); 214 | 215 | /* Store state in digest */ 216 | encode(_state, _digest, 16); 217 | 218 | /* Restore current state and count. */ 219 | memcpy(_state, oldState, 16); 220 | memcpy(_count, oldCount, 8); 221 | } 222 | 223 | /* MD5 basic transformation. Transforms _state based on block. */ 224 | void MD5::transform(const byte block[64]) { 225 | 226 | uint32 a = _state[0], b = _state[1], c = _state[2], d = _state[3], x[16]; 227 | 228 | decode(block, x, 64); 229 | 230 | /* Round 1 */ 231 | FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ 232 | FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ 233 | FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ 234 | FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ 235 | FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ 236 | FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ 237 | FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ 238 | FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ 239 | FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ 240 | FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ 241 | FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ 242 | FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ 243 | FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ 244 | FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ 245 | FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ 246 | FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ 247 | 248 | /* Round 2 */ 249 | GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ 250 | GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ 251 | GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ 252 | GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ 253 | GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ 254 | GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */ 255 | GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ 256 | GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ 257 | GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ 258 | GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ 259 | GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ 260 | GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ 261 | GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ 262 | GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ 263 | GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ 264 | GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ 265 | 266 | /* Round 3 */ 267 | HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ 268 | HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ 269 | HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ 270 | HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ 271 | HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ 272 | HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ 273 | HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ 274 | HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ 275 | HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ 276 | HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ 277 | HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ 278 | HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ 279 | HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ 280 | HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ 281 | HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ 282 | HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ 283 | 284 | /* Round 4 */ 285 | II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ 286 | II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ 287 | II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ 288 | II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ 289 | II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ 290 | II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ 291 | II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ 292 | II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ 293 | II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ 294 | II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ 295 | II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ 296 | II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ 297 | II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ 298 | II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ 299 | II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ 300 | II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ 301 | 302 | _state[0] += a; 303 | _state[1] += b; 304 | _state[2] += c; 305 | _state[3] += d; 306 | } 307 | 308 | /* Encodes input (ulong) into output (byte). Assumes length is 309 | a multiple of 4. 310 | */ 311 | void MD5::encode(const uint32* input, byte* output, size_t length) { 312 | 313 | for (size_t i = 0, j = 0; j < length; ++i, j += 4) { 314 | output[j]= (byte)(input[i] & 0xff); 315 | output[j + 1] = (byte)((input[i] >> 8) & 0xff); 316 | output[j + 2] = (byte)((input[i] >> 16) & 0xff); 317 | output[j + 3] = (byte)((input[i] >> 24) & 0xff); 318 | } 319 | } 320 | 321 | /* Decodes input (byte) into output (ulong). Assumes length is 322 | a multiple of 4. 323 | */ 324 | void MD5::decode(const byte* input, uint32* output, size_t length) { 325 | 326 | for (size_t i = 0, j = 0; j < length; ++i, j += 4) { 327 | output[i] = ((uint32)input[j]) | (((uint32)input[j + 1]) << 8) | 328 | (((uint32)input[j + 2]) << 16) | (((uint32)input[j + 3]) << 24); 329 | } 330 | } 331 | 332 | /* Convert byte array to hex string. */ 333 | string MD5::bytesToHexString(const byte* input, size_t length) { 334 | 335 | string str; 336 | str.reserve(length << 1); 337 | for (size_t i = 0; i < length; ++i) { 338 | int t = input[i]; 339 | int a = t / 16; 340 | int b = t % 16; 341 | str.append(1, HEX[a]); 342 | str.append(1, HEX[b]); 343 | } 344 | return str; 345 | } 346 | 347 | /* Convert digest to string value */ 348 | string MD5::toString() { 349 | return bytesToHexString(digest(), 16); 350 | } 351 | 352 | -------------------------------------------------------------------------------- /CloudPan1.0/client/md5.h: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | > File Name: md5.h 3 | > Author: qinyu 4 | > Mail: qinyu.LT@gmail.com 5 | > Created Time: 2016年04月21日 星期四 23时21分41秒 6 | ************************************************************************/ 7 | #ifndef MD5_H 8 | #define MD5_H 9 | 10 | #include 11 | #include 12 | 13 | /* Type define */ 14 | typedef unsigned char byte; 15 | typedef unsigned int uint32; 16 | 17 | using std::string; 18 | using std::ifstream; 19 | 20 | /* MD5 declaration. */ 21 | class MD5 { 22 | public: 23 | MD5(); 24 | MD5(const void* input, size_t length); 25 | MD5(const string& str); 26 | MD5(ifstream& in); 27 | void update(const void* input, size_t length); 28 | void update(const string& str); 29 | void update(ifstream& in); 30 | const byte* digest(); 31 | string toString(); 32 | void reset(); 33 | 34 | private: 35 | void update(const byte* input, size_t length); 36 | void final(); 37 | void transform(const byte block[64]); 38 | void encode(const uint32* input, byte* output, size_t length); 39 | void decode(const byte* input, uint32* output, size_t length); 40 | string bytesToHexString(const byte* input, size_t length); 41 | 42 | /* class uncopyable */ 43 | MD5(const MD5&); 44 | MD5& operator=(const MD5&); 45 | 46 | private: 47 | uint32 _state[4]; /* state (ABCD) */ 48 | uint32 _count[2]; /* number of bits, modulo 2^64 (low-order word first) */ 49 | byte _buffer[64]; /* input buffer */ 50 | byte _digest[16]; /* message digest */ 51 | bool _finished; /* calculate finished ? */ 52 | 53 | static const byte PADDING[64]; /* padding for calculate */ 54 | static const char HEX[16]; 55 | enum { BUFFER_SIZE = 1024 }; 56 | }; 57 | 58 | #endif /*MD5_H*/ 59 | 60 | -------------------------------------------------------------------------------- /CloudPan1.0/public.h: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | > File Name: public.h 3 | > Author: qinyu 4 | > Mail: qinyu.LT@gmail.com 5 | > Created Time: 2016年04月19日 星期二 22时30分55秒 6 | ************************************************************************/ 7 | #ifndef _PUBLIC_H 8 | #define _PUBLIC_H 9 | 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 | #include 23 | #include 24 | #include //stringstream 25 | #include 26 | #include 27 | #include 28 | 29 | using namespace std; 30 | 31 | #define CPT 6666 //管理端口 32 | #define TPT 6667 //传输端口 33 | #define MPT 6668 //聊天端口 34 | #define MCA 11211 //memcached端口 35 | 36 | #define SERADDR "127.0.0.1" 37 | #define DBUSER "root" 38 | #define DBPSSW "root" 39 | #define DBNAME "CloudPan" 40 | 41 | #define SER_HOME_PATH "/home/yourname/CloudPan/serdir" //服务端文件存储路径 42 | #define CLI_HOME_PATH "/home/yourname/CloudPan/clidir" //客户端文件存储路径 43 | 44 | #define BUFFSIZE 128 45 | 46 | #define ERR_EXIT(m) \ 47 | do \ 48 | { \ 49 | perror(m); \ 50 | exit(EXIT_FAILURE); \ 51 | }while(0) 52 | 53 | #define EPOLL_SIZE 50 54 | 55 | //用户操作类型 56 | enum OP_TYPE{ERR=-1,ENTER=1,REGISTER=2,UPLODE=3,DOWNLOAD=4,CHART=5,RM=6,LS=7}; 57 | 58 | //用户信息 59 | typedef struct Msg 60 | { 61 | OP_TYPE type; 62 | string user_id; 63 | string password; 64 | }msgInfo; 65 | 66 | //文件头部信息 67 | struct fileinfo 68 | { 69 | string file_name; //文件名 70 | string file_MD5; //文件MD5值 71 | string file_path; //文件存储路径 72 | int file_size; //文件大小 73 | int file_chunk_size; //分块个数 74 | int chunk_size; //分块标准 75 | bool trans_status; //传输状态 76 | }; 77 | //文件信息 78 | struct filedata 79 | { 80 | string file_name; //文件名 81 | int id; //分块id 82 | int offset; //该块在文件的偏移量 83 | bool trans_status; //传输状态 84 | }; 85 | 86 | #endif 87 | -------------------------------------------------------------------------------- /CloudPan1.0/readme.md: -------------------------------------------------------------------------------- 1 | ##这里包含一些编程过程中的记录,遇到的问题 2 | .... 3 | ```cpp 4 | 服务器端安全可靠的后台运行工具: 5 | nohup ./ser > serLog.out 2>&1 & 6 | nohup ./FTS > FTSLog.out 2>&1 & 7 | 8 | 服务器端输出重定向到:serLog.out 和 FTSLog.out 9 | 使用 jobs 查看任务 10 | 使用 fg %n 关闭 11 | 12 | 13 | //查找用户‘qqq’的文件列表 14 | select user_id,filename,size,type from user,files where user.user_id='qqq' and user.file_id=files.id; 15 | //查找用户‘qqq’的好友列表 16 | select friends.user_id from user,friends where user.user_id='qqq' and user.friends_id=friends.id; 17 | 18 | //注册用户 19 | insert into user(user_id,password) select '用户名','密码' from dual where not exists(select *from user where user.user_id='用户名'); 20 | 21 | //编译mysql需要加上 22 | -L/usr/lib/mysql -lmysqlclient 23 | 24 | //编译mysql连接池时,使用的时libmysqlcppconn接口,需要加上 25 | -L/usr/lib/mysql -lmysqlcppconn 26 | 27 | //用于 用户登录 查询,存在返回记录条数,不存在返回0 28 | select exists(select *from user where user_id='用户名' and password='密码'); 29 | 30 | //mysql编译 31 | g++ -o MyDB MyDB.cpp MyDB.h public.h -L/usr/lib/mysql -lmysqlclient 32 | 33 | //问题1:undefined reference to `conCli::do_work()' 34 | //需将引用到的.cpp文件生成.a库文件 35 | g++ -c conCli.cpp //.o 36 | ar -rc conCli.a conCli.o 37 | //编译时加上生成的.a库文件 38 | 39 | //客户端生成可执行文件 40 | g++ -o Cli testcli.cpp conCli.a 41 | //服务器端生成可执行文件 42 | g++ -c conSer.cpp 43 | ar -rc conCli.a conCli.o 44 | g++ -o Ser testser.cpp conSer.a 45 | 46 | 47 | //问题2: multiple definition of `msg' 48 | 在所以全局变量前加static关键字或在public.h头文件声明extern关键字 49 | 50 | //问题3:错误:no match 为‘operator<’在‘std::bind(_Functor, _ArgTypes ...) [with _Functor = int, _ArgTypes = sockaddr*, unsigned int](((sockaddr*)(&((conSer*)this)->conSer::seraddr)), 16u) < 0’中 51 | 由于memcached的调用涉及到C++11标准(即在编译时需要加上--std=gnu++0x),所以Socket下的bind()函数和STL下的bind()函数发生冲突 52 | 解决方法: 53 | 1.在使用socket下的bind()函数所在的类中禁止使用using namespace std;由于调试需要,这种办法不可取 54 | 2.在使用socket下的bind()函数时,在bind()前加“::”运算符 55 | 56 | memcached启动: 57 | /usr/local/bin/memcached -m 10 -u root -l 127.0.0.1 -p 11211 -c 256 -vv 58 | ``` 59 | 60 | ```cpp 61 | "Segmentation Fault" 62 | 段错误是指访问的内存超出了系统给这个程序所设定的内存: 63 | 1、访问不存在的内存地址 64 | 2、访问系统保护的内存地址 65 | 3、访问只读的内存地址 66 | 4、栈溢出 67 | 68 | 查看详细的段错误信息: 69 | 1、dmesg: 通过dmesg命令可以查看发送段错误的程序名称、引起段错误发生的内存地址、指令指针地址、堆栈指针地址、错误代码、错误原因等 70 | 2、gcc/g++编译程序源码加上-g参数,用于gdb调试,显示错误信息(但是多进程下gdb调试比较困难,我一般用cout在关键地方输出信息) 71 | 3、nm ./可执行程序:列出二进制文件中的符号表(符号地址、类型、名),可以帮助定位错误地方 72 | 4、ldd ./可执行程序: 查看二进制程序的共享链接库依赖,包括库的名称、起始地址,可确定段错误发生的库(自己的库还是依赖的库) 73 | 5、objdump: 先用dmesg找出最近发生的段错误输出信息(段错误地址、指令指针地址) 74 | 然后使用objdump生成二进制的相关信息:objdump -d ./可执行程序 > dumpfile 75 | dumpfile重定向文件包含可执行程序的汇编代码,从中查找dmesg输出的发生错误的地址,定位原程序 76 | 注意事项 77 | 段错误主要出现在指针的使用地方,定义时初始化,使用时判 NULL,Glibc库中基本所有的函数默认形参指针为非空 78 | 数组下标是否越界,数组元素是否存在 79 | 是否访问了已经释放的空间 80 | printf/scanf的格式控制是否合理 81 | ``` 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /CloudPan1.0/server/FTS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qinyuLT/CloudPan/65cdb6220ab26d43cca368cc5423bca2df1f040d/CloudPan1.0/server/FTS -------------------------------------------------------------------------------- /CloudPan1.0/server/FTSLog.out: -------------------------------------------------------------------------------- 1 | nohup: 忽略输入 2 | -------------------------------------------------------------------------------- /CloudPan1.0/server/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY:clean all 2 | exec: 3 | #g++ -c md5.cpp; 4 | #ar -rc md5.a md5.o; 5 | #g++ -c MyDB.cpp; 6 | #ar -rc MyDB.a MyDB.o; 7 | 8 | #g++ -o cli conCli.cpp md5.a; 9 | #g++ -o cli testcli.cpp conCli.a md5.a; 10 | #g++ -o ser conSer.cpp MyDB.a -L/usr/lib/mysql -lmysqlclient --std=c++0x; 11 | #g++ -o cli conCli.cpp md5.cpp 12 | 13 | g++ -o ser conSer.cpp MyDB.cpp -I /usr/include/libmemcached/include -L/usr/include/libmemcached/lib -L/usr/lib/mysql -lmysqlclient -lmemcached -lpthread --std=gnu++0x; 14 | g++ -o FTS fileTrans.cpp md5.cpp MyDB.cpp -I /usr/include/libmemcached/include -L/usr/include/libmemcached/lib -L/usr/lib/mysql -lmysqlclient -lmemcached -lpthread --std=gnu++0x; 15 | clean: 16 | rm -f *.o; 17 | rm -f *~; 18 | rm *.a; 19 | 20 | 21 | -------------------------------------------------------------------------------- /CloudPan1.0/server/MyDB.cpp: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | > File Name: MyDB.cpp 3 | > Author: qinyu 4 | > Mail: qinyu.LT@gmail.com 5 | > Created Time: 2016年04月19日 星期二 22时57分44秒 6 | ************************************************************************/ 7 | 8 | #include "MyDB.h" 9 | #include 10 | using namespace std; 11 | 12 | MyDB::MyDB() 13 | { 14 | connection = mysql_init(NULL); 15 | if(connection == NULL) 16 | { 17 | cout<<"Errorr"< MyDB::getResult() 81 | { 82 | return res; 83 | } 84 | 85 | void MyDB::showResult() 86 | { 87 | cout<<"showResult():"; 88 | cout<::iterator it; 90 | for(it=res.begin();it != res.end();++it) 91 | { 92 | cout<<*it< File Name: MyDB.h 3 | > Author: qinyu 4 | > Mail: qinyu.LT@gmail.com 5 | > Created Time: 2016年04月19日 星期二 22时57分10秒 6 | ************************************************************************/ 7 | #ifndef _MYDB_H 8 | #define _MYDB_H 9 | 10 | #include "../public.h" 11 | #include "/usr/include/mysql/mysql.h" 12 | 13 | class MyDB 14 | { 15 | public: 16 | MyDB(); 17 | ~MyDB(); 18 | bool initDB(string host,string user,string password,string db_name); 19 | bool execSQL(string sql); 20 | void showResult(); 21 | list getResult(); 22 | private: 23 | MYSQL *connection; 24 | MYSQL_RES *result; 25 | MYSQL_ROW row; 26 | list res; 27 | }; 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /CloudPan1.0/server/chart.cpp: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | > File Name: chart.cpp 3 | > Author: qinyu 4 | > Mail: qinyu.LT@gmail.com 5 | > Created Time: 2016年04月22日 星期五 22时40分18秒 6 | ************************************************************************/ 7 | 8 | #include "chart.h" 9 | int main() 10 | { 11 | return 0; 12 | } 13 | -------------------------------------------------------------------------------- /CloudPan1.0/server/chart.h: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | > File Name: chart.h 3 | > Author: qinyu 4 | > Mail: qinyu.LT@gmail.com 5 | > Created Time: 2016年04月22日 星期五 22时35分31秒 6 | ************************************************************************/ 7 | #ifndef _CHART_H 8 | #define _CHART_H 9 | 10 | #include "../public.h" 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /CloudPan1.0/server/conSer.cpp: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | > File Name: conSer.cpp 3 | > Author: qinyu 4 | > Mail: qinyu.LT@gmail.com 5 | > Created Time: 2016年04月20日 星期三 22时38分48秒 6 | ************************************************************************/ 7 | #include "MCache.h" 8 | #include "conSer.h" 9 | conSer::conSer(int port,const char *addr) 10 | { 11 | if((listenfd=socket(PF_INET,SOCK_STREAM,0)) < 0) 12 | ERR_EXIT("socket"); 13 | memset(&seraddr,0,sizeof(seraddr)); 14 | seraddr.sin_family = AF_INET; 15 | seraddr.sin_port = htons(port); 16 | seraddr.sin_addr.s_addr = htonl(INADDR_ANY); 17 | } 18 | 19 | conSer::~conSer(){}//delete db;} 20 | 21 | void conSer::Socket() 22 | { 23 | int on = 1; 24 | if(setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on)) < 0 ) 25 | ERR_EXIT("setsockopt"); 26 | } 27 | 28 | void conSer::Bind() 29 | { 30 | if(::bind(listenfd,(struct sockaddr*)&seraddr,sizeof(seraddr)) < 0 ) 31 | ERR_EXIT("bind"); 32 | } 33 | 34 | void conSer::Listen() 35 | { 36 | if(listen(listenfd,SOMAXCONN) < 0) 37 | ERR_EXIT("listen"); 38 | } 39 | 40 | //采用select方法: 41 | /*int conSer::accept_timeout(unsigned int wait_seconds) 42 | { 43 | int ret; 44 | socklen_t peerlen = sizeof(peeraddr); 45 | 46 | if(wait_seconds > 0) 47 | { 48 | fd_set accept_fdset; 49 | struct timeval timeout; 50 | FD_ZERO(&accept_fdset); 51 | FD_SET(listenfd,&accept_fdset); 52 | timeout.tv_sec = wait_seconds; 53 | timeout.tv_usec = 0; 54 | 55 | do{ 56 | ret = select(listenfd+1,&accept_fdset,NULL,NULL,&timeout); 57 | }while(ret<0 && errno == EINTR); 58 | 59 | if(ret == -1) 60 | { 61 | return -1; 62 | } 63 | else if(ret == 0) 64 | { 65 | errno = ETIMEDOUT; 66 | return -1; 67 | } 68 | } 69 | 70 | if(&peeraddr != NULL) 71 | ret = accept(listenfd,(struct sockaddr*)&peeraddr,&peerlen); 72 | else 73 | ret = accept(listenfd,NULL,NULL); 74 | 75 | return ret; 76 | } 77 | */ 78 | 79 | //int conSer::accept_timeout(unsigned int wait_seconds) 80 | //采用epoll方法: 81 | void conSer::epoll_work() 82 | { 83 | struct epoll_event ev,events[EPOLL_SIZE]; 84 | int epfd = epoll_create(EPOLL_SIZE); 85 | ev.events = EPOLLIN; 86 | ev.data.fd = listenfd; 87 | epoll_ctl(epfd,EPOLL_CTL_ADD,listenfd,&ev); 88 | 89 | while(1) 90 | { 91 | int events_count = epoll_wait(epfd,events,EPOLL_SIZE,-1); 92 | int i=0; 93 | 94 | for(;i0) 104 | { 105 | cout<>port; 208 | msg += FTS_IP+" "+port; 209 | } 210 | 211 | void conSer::get_cmd() 212 | { 213 | char *ptr = (char*)msg.c_str(); 214 | char *cmd = strtok(ptr," "); 215 | string sqlExec; 216 | int select; 217 | //cout<initDB(SERADDR,DBUSER,DBPSSW,DBNAME)) 227 | { 228 | msg = "ser error(mysql connecting)"; 229 | select = -1; 230 | }else 231 | { 232 | select = atoi(cmd); 233 | } 234 | 235 | string userid=*(sql.begin()); 236 | sql.pop_front(); 237 | string passwd=*(sql.begin()); 238 | sql.pop_front(); 239 | 240 | MCache mem(SERADDR,MCA); 241 | //mem.insertValue(userid.c_str(),passwd.c_str(),180); 242 | 243 | //cout<<"user:"<execSQL(sqlExec); 252 | msg=*(db->getResult()).begin(); 253 | */ 254 | //MCache mem(SERADDR,MCA); 255 | if(strncmp(mem.getValue(userid.c_str()),passwd.c_str(),32) == 0) 256 | { 257 | msg = "1"; 258 | }else 259 | { 260 | msg = "userid or passwd error!"; 261 | } 262 | break; 263 | 264 | //注册:插入mysql数据库并且插入到memcached缓存中 265 | case REGISTER: 266 | //insert into user(user_id,password) select '用户名','密码' from dual where not exists(select *from user where user.user_id='用户名'); 267 | sqlExec="select exists (select *from user where user_id='"+userid+"')"; 268 | db->execSQL(sqlExec); 269 | msg=*(db->getResult()).begin(); 270 | if(strncmp("1",msg.c_str(),1) == 0) 271 | { 272 | msg = "The user existed!"; 273 | }else{ 274 | 275 | sqlExec="insert into user(user_id,password) select '"+userid+"','"+passwd+"' from dual where not exists(select *from user where user.user_id='"+userid+"')"; 276 | db->execSQL(sqlExec); 277 | msg = "register success!"; 278 | } 279 | //插入memcached 280 | //MCache mem(SERADDR,MCA); 281 | mem.insertValue(userid.c_str(),passwd.c_str(),180); 282 | break; 283 | 284 | case UPLODE: 285 | msg = "3 "; 286 | selectFTServer(); 287 | break; 288 | 289 | case DOWNLOAD: 290 | msg = "4 "; 291 | selectFTServer(); 292 | break; 293 | 294 | case CHART: 295 | //msg = "5 "; 296 | //selectCServer(); 297 | break; 298 | 299 | break; 300 | } 301 | } 302 | 303 | 304 | int main() 305 | { 306 | conSer ser(CPT,SERADDR); 307 | ser.Run(); 308 | 309 | return 0; 310 | } 311 | -------------------------------------------------------------------------------- /CloudPan1.0/server/conSer.h: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | > File Name: conSer.h 3 | > Author: qinyu 4 | > Mail: qinyu.LT@gmail.com 5 | > Created Time: 2016年04月19日 星期二 22时51分03秒 6 | ************************************************************************/ 7 | 8 | #ifndef CONSER_H 9 | #define CONSER_H 10 | #include "../public.h" 11 | #include "MyDB.h" 12 | #include "sqlConnPool.h" 13 | 14 | class conSer 15 | { 16 | public: 17 | 18 | conSer(int port,const char *addr); 19 | ~conSer(); 20 | void Socket(); 21 | void Bind(); 22 | void Listen(); 23 | int accept_timeout(unsigned int wait_seconds);//select 24 | void epoll_work(); //epoll 25 | void Run(); 26 | 27 | private: 28 | void selectFTServer(); 29 | //selectCServer(); 30 | void do_service(int conn); 31 | void get_cmd(); 32 | 33 | private: 34 | int listenfd; 35 | int port; 36 | char *addr; 37 | list sql; 38 | string msg; 39 | //msgInfo msg; 40 | struct sockaddr_in seraddr,peeraddr; 41 | //MyDB *db; 42 | }; 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /CloudPan1.0/server/fileTrans.cpp: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | > File Name: fileTrans.cpp 3 | > Author: qinyu 4 | > Mail: qinyu.LT@gmail.com 5 | > Created Time: 2016年04月22日 星期五 12时55分04秒 6 | ************************************************************************/ 7 | 8 | #include "md5.h" 9 | #include "MCache.h" 10 | #include "MyDB.h" 11 | #include "fileTrans.h" 12 | 13 | FileTrans::FileTrans(int port,const char *addr) 14 | { 15 | if((trans_fd=socket(PF_INET,SOCK_STREAM,0)) < 0) 16 | ERR_EXIT("socket"); 17 | memset(&seraddr,0,sizeof(seraddr)); 18 | seraddr.sin_family = AF_INET; 19 | seraddr.sin_port = htons(port); 20 | seraddr.sin_addr.s_addr = htonl(INADDR_ANY); 21 | 22 | int on = 1; 23 | if(setsockopt(trans_fd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on)) < 0 ) 24 | ERR_EXIT("setsockopt"); 25 | if(::bind(trans_fd,(struct sockaddr*)&seraddr,sizeof(seraddr)) < 0 ) 26 | ERR_EXIT("bind"); 27 | if(listen(trans_fd,SOMAXCONN) < 0) 28 | ERR_EXIT("listen"); 29 | } 30 | 31 | FileTrans::~FileTrans() 32 | { 33 | close(trans_fd); 34 | close(connfd); 35 | } 36 | 37 | void FileTrans::Run() 38 | { 39 | struct epoll_event ev,events[EPOLL_SIZE]; 40 | int epfd = epoll_create(EPOLL_SIZE); 41 | ev.events = EPOLLIN; 42 | ev.data.fd = trans_fd; 43 | epoll_ctl(epfd,EPOLL_CTL_ADD,trans_fd,&ev); 44 | 45 | while(1) 46 | { 47 | int events_count = epoll_wait(epfd,events,EPOLL_SIZE,-1); 48 | int i=0; 49 | 50 | for(;i 0) 58 | { 59 | cout<<"---------FileTrans-Server-----------"<initDB(SERADDR,DBUSER,DBPSSW,DBNAME)) 143 | { 144 | msg = "ser error(mysql connecting)"; 145 | return; 146 | } 147 | string selectSql = "select *from files where user_id="+user_id+" and file_path="+m_fileinfo.file_path; 148 | db->execSQL(selectSql); 149 | sql = db->getResult(); 150 | getFileInfo(); 151 | write(connfd,&m_fileinfo,sizeof(m_fileinfo)); 152 | } 153 | bool FileTrans::recvFile() 154 | { 155 | //秒传的实现:检查以文件MD5为key的value是否存在mcached中 156 | MCache mem(SERADDR,MCA); 157 | MyDB *db = new MyDB(); 158 | if(mem.getValue(m_fileinfo.file_MD5.c_str()) == NULL) 159 | { 160 | if(createFile() == false) 161 | ERR_EXIT("open file"); 162 | //创建文件成功,匹配MD5,需要给出存储文件的全路径名 163 | if(strncmp((m_fileinfo.file_MD5).c_str(),(MD5(m_fileinfo.file_path).toString()).c_str(),32) != 0) 164 | { 165 | ERR_EXIT("File md5 error"); 166 | } 167 | m_fileinfo.trans_status = true; 168 | //文件真正传输成功,存入memcached 169 | //以文件MD5值作为key,文件名作为value存入memcached 170 | mem.insertValue((m_fileinfo.file_MD5).c_str(),(m_fileinfo.file_name).c_str(),180); 171 | } 172 | //存入mysql 173 | if(!db->initDB(SERADDR,DBUSER,DBPSSW,DBNAME)) 174 | { 175 | msg = "ser error(mysql connecting)"; 176 | } 177 | stringstream ss; 178 | string tmp; 179 | string status; 180 | ss<>tmp; 182 | if(m_fileinfo.trans_status) 183 | status = "ok"; 184 | else 185 | status = "er"; 186 | string insertSql = "insert into files values("+m_fileinfo.file_name+","+user_id+","+m_fileinfo.file_MD5+","+m_fileinfo.file_path+","+tmp+","+status+");"; 187 | db->execSQL(insertSql); 188 | 189 | msg=*(db->getResult()).begin(); 190 | if(strncmp("1",msg.c_str(),1) == 0) 191 | { 192 | msg = "file insert to mysql error!"; 193 | } 194 | return true; 195 | } 196 | 197 | bool FileTrans::sendFile() 198 | { 199 | int fd = open((m_fileinfo.file_path).c_str(), O_RDONLY); 200 | if(fd < 0) 201 | { 202 | //ERR_EXIT("open file"); 203 | cout<<"open file false"<initDB(SERADDR,DBUSER,DBPSSW,DBNAME)) 216 | { 217 | msg = "ser error(mysql connecting)"; 218 | return false; 219 | } 220 | //查询user_id是否拥有path文件 221 | string selectSql="select count(*) from files where user_id="+user_id+"and file_path="+path ; 222 | db->execSQL(selectSql); 223 | msg = *(db->getResult()).begin(); 224 | if(strncmp("1",msg.c_str(),1) != 0) 225 | { 226 | msg = "The user does not have this file"; 227 | return false; 228 | } 229 | //删除memcached记录,需要从mysql查询key值,即file_MD5 230 | selectSql = "select file_MD5 from files where user_id="+user_id+" and file_path="+path; 231 | db->execSQL(selectSql); 232 | 233 | MCache mem(SERADDR,MCA); 234 | mem.deleteKey((*(db->getResult()).begin()).c_str()); 235 | //删除mysql记录 236 | selectSql = "delete from files where user_id="+user_id+"and file_path="+path; 237 | db->execSQL(selectSql); 238 | 239 | return true; 240 | } 241 | 242 | bool FileTrans::createFile() 243 | { 244 | int nbytes = -1; 245 | //while (true) 246 | //{ 247 | int fd = open((m_fileinfo.file_path).c_str(), O_WRONLY|O_CREAT|O_TRUNC, 0666); 248 | if (fd == -1) 249 | { 250 | ERR_EXIT("open file error"); 251 | return false; 252 | } 253 | //recive file 254 | char recvBuf[BUFFSIZE]={0}; 255 | while((nbytes=recv(trans_fd,recvBuf,64,0)) > 0) 256 | { 257 | int writeBytes = write(fd,recvBuf,nbytes); 258 | if(writeBytes != nbytes) 259 | { 260 | ERR_EXIT("write file error"); 261 | return false; 262 | } 263 | if(nbytes < 64) 264 | { 265 | break; 266 | } 267 | } 268 | //} 269 | return true; 270 | } 271 | 272 | void FileTrans::showFileList() 273 | { 274 | MyDB *db = new MyDB(); 275 | if(!db->initDB(SERADDR,DBUSER,DBPSSW,DBNAME)) 276 | { 277 | msg = "ser error(mysql connecting)"; 278 | return; 279 | } 280 | //查询user_id的所有文件名 281 | string selectSql="select file_name from files where user_id="+user_id; 282 | db->execSQL(selectSql); 283 | list res=db->getResult(); 284 | //msg保存查询出来的文件名,以" "分开,传回客户端 285 | list::iterator it; 286 | for(it=res.begin();it!=res.end();++it) 287 | { 288 | msg += *it; 289 | msg += " "; 290 | } 291 | } 292 | 293 | int main() 294 | { 295 | FileTrans ft(TPT,SERADDR); 296 | ft.Run(); 297 | return 0; 298 | } 299 | -------------------------------------------------------------------------------- /CloudPan1.0/server/fileTrans.h: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | > File Name: fileTrans.h 3 | > Author: qinyu 4 | > Mail: qinyu.LT@gmail.com 5 | > Created Time: 2016年04月21日 星期三 12时54分19秒 6 | ************************************************************************/ 7 | 8 | #ifndef _FILETRANS_H 9 | #define _FILETRANS_H 10 | 11 | #include "../public.h" 12 | 13 | class FileTrans 14 | { 15 | public: 16 | FileTrans(int port,const char*addr); 17 | ~FileTrans(); 18 | void Run(); 19 | private: 20 | bool sendFile(); 21 | bool recvFile(); 22 | bool createFile(); 23 | bool removeFile(string path); 24 | void sendFileInfo(); 25 | void getFileInfo(); 26 | void showFileList(); 27 | void getCmd(); 28 | 29 | private: 30 | int trans_fd; 31 | int connfd; 32 | string user_id; 33 | string msg; 34 | list sql; 35 | struct fileinfo m_fileinfo; 36 | struct filedata m_filedata; 37 | struct sockaddr_in seraddr,peeraddr; 38 | }; 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /CloudPan1.0/server/main: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qinyuLT/CloudPan/65cdb6220ab26d43cca368cc5423bca2df1f040d/CloudPan1.0/server/main -------------------------------------------------------------------------------- /CloudPan1.0/server/main.cpp: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | > File Name: main.cpp 3 | > Author: qinyu 4 | > Mail: qinyu.LT@gmail.com 5 | > Created Time: 2016年04月19日 星期二 22时59分09秒 6 | ************************************************************************/ 7 | //#include "conSer.h" 8 | //#include "conCli.h" 9 | //#include "MyDB.h" 10 | //#include "md5.h" 11 | //#include "tPool.h" 12 | #include "MCache.h" 13 | #include 14 | using namespace std; 15 | 16 | int main() 17 | { 18 | MCache mem("127.0.0.1",11211); 19 | mem.insertValue("qinyu","123123",180); 20 | cout< File Name: md5.cpp 3 | > Author: qinyu 4 | > Mail: qinyu.LT@gmail.com 5 | > Created Time: 2016年04月21日 星期四 23时21分59秒 6 | ************************************************************************/ 7 | #include "md5.h" 8 | #include "../public.h" 9 | using namespace std; 10 | 11 | /* Constants for MD5Transform routine. */ 12 | #define S11 7 13 | #define S12 12 14 | #define S13 17 15 | #define S14 22 16 | #define S21 5 17 | #define S22 9 18 | #define S23 14 19 | #define S24 20 20 | #define S31 4 21 | #define S32 11 22 | #define S33 16 23 | #define S34 23 24 | #define S41 6 25 | #define S42 10 26 | #define S43 15 27 | #define S44 21 28 | 29 | 30 | /* F, G, H and I are basic MD5 functions. 31 | */ 32 | #define F(x, y, z) (((x) & (y)) | ((~x) & (z))) 33 | #define G(x, y, z) (((x) & (z)) | ((y) & (~z))) 34 | #define H(x, y, z) ((x) ^ (y) ^ (z)) 35 | #define I(x, y, z) ((y) ^ ((x) | (~z))) 36 | 37 | /* ROTATE_LEFT rotates x left n bits. 38 | */ 39 | #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) 40 | 41 | /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. 42 | Rotation is separate from addition to prevent recomputation. 43 | */ 44 | #define FF(a, b, c, d, x, s, ac) { \ 45 | (a) += F ((b), (c), (d)) + (x) + ac; \ 46 | (a) = ROTATE_LEFT ((a), (s)); \ 47 | (a) += (b); \ 48 | } 49 | #define GG(a, b, c, d, x, s, ac) { \ 50 | (a) += G ((b), (c), (d)) + (x) + ac; \ 51 | (a) = ROTATE_LEFT ((a), (s)); \ 52 | (a) += (b); \ 53 | } 54 | #define HH(a, b, c, d, x, s, ac) { \ 55 | (a) += H ((b), (c), (d)) + (x) + ac; \ 56 | (a) = ROTATE_LEFT ((a), (s)); \ 57 | (a) += (b); \ 58 | } 59 | #define II(a, b, c, d, x, s, ac) { \ 60 | (a) += I ((b), (c), (d)) + (x) + ac; \ 61 | (a) = ROTATE_LEFT ((a), (s)); \ 62 | (a) += (b); \ 63 | } 64 | 65 | 66 | const byte MD5::PADDING[64] = { 0x80 }; 67 | const char MD5::HEX[16] = { 68 | '0', '1', '2', '3', 69 | '4', '5', '6', '7', 70 | '8', '9', 'a', 'b', 71 | 'c', 'd', 'e', 'f' 72 | }; 73 | 74 | 75 | /* Default construct. */ 76 | MD5::MD5() { 77 | reset(); 78 | } 79 | 80 | /* Construct a MD5 object with a input buffer. */ 81 | MD5::MD5(const void* input, size_t length) { 82 | reset(); 83 | update(input, length); 84 | } 85 | 86 | /* Construct a MD5 object with a string. */ 87 | MD5::MD5(const string& str) { 88 | reset(); 89 | update(str); 90 | } 91 | 92 | /* Construct a MD5 object with a file. */ 93 | MD5::MD5(ifstream& in) { 94 | reset(); 95 | update(in); 96 | } 97 | 98 | /* Return the message-digest */ 99 | const byte* MD5::digest() { 100 | 101 | if (!_finished) { 102 | _finished = true; 103 | final(); 104 | } 105 | return _digest; 106 | } 107 | 108 | /* Reset the calculate state */ 109 | void MD5::reset() { 110 | 111 | _finished = false; 112 | /* reset number of bits. */ 113 | _count[0] = _count[1] = 0; 114 | /* Load magic initialization constants. */ 115 | _state[0] = 0x67452301; 116 | _state[1] = 0xefcdab89; 117 | _state[2] = 0x98badcfe; 118 | _state[3] = 0x10325476; 119 | } 120 | 121 | /* Updating the context with a input buffer. */ 122 | void MD5::update(const void* input, size_t length) { 123 | update((const byte*)input, length); 124 | } 125 | 126 | /* Updating the context with a string. */ 127 | void MD5::update(const string& str) { 128 | update((const byte*)str.c_str(), str.length()); 129 | } 130 | 131 | /* Updating the context with a file. */ 132 | void MD5::update(ifstream& in) { 133 | 134 | if (!in) { 135 | return; 136 | } 137 | 138 | std::streamsize length; 139 | char buffer[BUFFER_SIZE]; 140 | while (!in.eof()) { 141 | in.read(buffer, BUFFER_SIZE); 142 | length = in.gcount(); 143 | if (length > 0) { 144 | update(buffer, length); 145 | } 146 | } 147 | in.close(); 148 | } 149 | 150 | /* MD5 block update operation. Continues an MD5 message-digest 151 | operation, processing another message block, and updating the 152 | context. 153 | */ 154 | void MD5::update(const byte* input, size_t length) { 155 | 156 | uint32 i, index, partLen; 157 | 158 | _finished = false; 159 | 160 | /* Compute number of bytes mod 64 */ 161 | index = (uint32)((_count[0] >> 3) & 0x3f); 162 | 163 | /* update number of bits */ 164 | if ((_count[0] += ((uint32)length << 3)) < ((uint32)length << 3)) { 165 | ++_count[1]; 166 | } 167 | _count[1] += ((uint32)length >> 29); 168 | 169 | partLen = 64 - index; 170 | 171 | /* transform as many times as possible. */ 172 | if (length >= partLen) { 173 | 174 | memcpy(&_buffer[index], input, partLen); 175 | transform(_buffer); 176 | 177 | for (i = partLen; i + 63 < length; i += 64) { 178 | transform(&input[i]); 179 | } 180 | index = 0; 181 | 182 | } else { 183 | i = 0; 184 | } 185 | 186 | /* Buffer remaining input */ 187 | memcpy(&_buffer[index], &input[i], length - i); 188 | } 189 | 190 | /* MD5 finalization. Ends an MD5 message-_digest operation, writing the 191 | the message _digest and zeroizing the context. 192 | */ 193 | void MD5::final() { 194 | 195 | byte bits[8]; 196 | uint32 oldState[4]; 197 | uint32 oldCount[2]; 198 | uint32 index, padLen; 199 | 200 | /* Save current state and count. */ 201 | memcpy(oldState, _state, 16); 202 | memcpy(oldCount, _count, 8); 203 | 204 | /* Save number of bits */ 205 | encode(_count, bits, 8); 206 | 207 | /* Pad out to 56 mod 64. */ 208 | index = (uint32)((_count[0] >> 3) & 0x3f); 209 | padLen = (index < 56) ? (56 - index) : (120 - index); 210 | update(PADDING, padLen); 211 | 212 | /* Append length (before padding) */ 213 | update(bits, 8); 214 | 215 | /* Store state in digest */ 216 | encode(_state, _digest, 16); 217 | 218 | /* Restore current state and count. */ 219 | memcpy(_state, oldState, 16); 220 | memcpy(_count, oldCount, 8); 221 | } 222 | 223 | /* MD5 basic transformation. Transforms _state based on block. */ 224 | void MD5::transform(const byte block[64]) { 225 | 226 | uint32 a = _state[0], b = _state[1], c = _state[2], d = _state[3], x[16]; 227 | 228 | decode(block, x, 64); 229 | 230 | /* Round 1 */ 231 | FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ 232 | FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ 233 | FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ 234 | FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ 235 | FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ 236 | FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ 237 | FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ 238 | FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ 239 | FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ 240 | FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ 241 | FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ 242 | FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ 243 | FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ 244 | FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ 245 | FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ 246 | FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ 247 | 248 | /* Round 2 */ 249 | GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ 250 | GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ 251 | GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ 252 | GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ 253 | GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ 254 | GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */ 255 | GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ 256 | GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ 257 | GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ 258 | GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ 259 | GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ 260 | GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ 261 | GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ 262 | GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ 263 | GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ 264 | GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ 265 | 266 | /* Round 3 */ 267 | HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ 268 | HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ 269 | HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ 270 | HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ 271 | HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ 272 | HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ 273 | HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ 274 | HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ 275 | HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ 276 | HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ 277 | HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ 278 | HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ 279 | HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ 280 | HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ 281 | HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ 282 | HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ 283 | 284 | /* Round 4 */ 285 | II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ 286 | II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ 287 | II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ 288 | II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ 289 | II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ 290 | II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ 291 | II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ 292 | II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ 293 | II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ 294 | II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ 295 | II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ 296 | II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ 297 | II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ 298 | II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ 299 | II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ 300 | II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ 301 | 302 | _state[0] += a; 303 | _state[1] += b; 304 | _state[2] += c; 305 | _state[3] += d; 306 | } 307 | 308 | /* Encodes input (ulong) into output (byte). Assumes length is 309 | a multiple of 4. 310 | */ 311 | void MD5::encode(const uint32* input, byte* output, size_t length) { 312 | 313 | for (size_t i = 0, j = 0; j < length; ++i, j += 4) { 314 | output[j]= (byte)(input[i] & 0xff); 315 | output[j + 1] = (byte)((input[i] >> 8) & 0xff); 316 | output[j + 2] = (byte)((input[i] >> 16) & 0xff); 317 | output[j + 3] = (byte)((input[i] >> 24) & 0xff); 318 | } 319 | } 320 | 321 | /* Decodes input (byte) into output (ulong). Assumes length is 322 | a multiple of 4. 323 | */ 324 | void MD5::decode(const byte* input, uint32* output, size_t length) { 325 | 326 | for (size_t i = 0, j = 0; j < length; ++i, j += 4) { 327 | output[i] = ((uint32)input[j]) | (((uint32)input[j + 1]) << 8) | 328 | (((uint32)input[j + 2]) << 16) | (((uint32)input[j + 3]) << 24); 329 | } 330 | } 331 | 332 | /* Convert byte array to hex string. */ 333 | string MD5::bytesToHexString(const byte* input, size_t length) { 334 | 335 | string str; 336 | str.reserve(length << 1); 337 | for (size_t i = 0; i < length; ++i) { 338 | int t = input[i]; 339 | int a = t / 16; 340 | int b = t % 16; 341 | str.append(1, HEX[a]); 342 | str.append(1, HEX[b]); 343 | } 344 | return str; 345 | } 346 | 347 | /* Convert digest to string value */ 348 | string MD5::toString() { 349 | return bytesToHexString(digest(), 16); 350 | } 351 | 352 | -------------------------------------------------------------------------------- /CloudPan1.0/server/md5.h: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | > File Name: md5.h 3 | > Author: qinyu 4 | > Mail: qinyu.LT@gmail.com 5 | > Created Time: 2016年04月21日 星期四 23时21分41秒 6 | ************************************************************************/ 7 | #ifndef MD5_H 8 | #define MD5_H 9 | 10 | #include 11 | #include 12 | 13 | /* Type define */ 14 | typedef unsigned char byte; 15 | typedef unsigned int uint32; 16 | 17 | using std::string; 18 | using std::ifstream; 19 | 20 | /* MD5 declaration. */ 21 | class MD5 { 22 | public: 23 | MD5(); 24 | MD5(const void* input, size_t length); 25 | MD5(const string& str); 26 | MD5(ifstream& in); 27 | void update(const void* input, size_t length); 28 | void update(const string& str); 29 | void update(ifstream& in); 30 | const byte* digest(); 31 | string toString(); 32 | void reset(); 33 | 34 | private: 35 | void update(const byte* input, size_t length); 36 | void final(); 37 | void transform(const byte block[64]); 38 | void encode(const uint32* input, byte* output, size_t length); 39 | void decode(const byte* input, uint32* output, size_t length); 40 | string bytesToHexString(const byte* input, size_t length); 41 | 42 | /* class uncopyable */ 43 | MD5(const MD5&); 44 | MD5& operator=(const MD5&); 45 | 46 | private: 47 | uint32 _state[4]; /* state (ABCD) */ 48 | uint32 _count[2]; /* number of bits, modulo 2^64 (low-order word first) */ 49 | byte _buffer[64]; /* input buffer */ 50 | byte _digest[16]; /* message digest */ 51 | bool _finished; /* calculate finished ? */ 52 | 53 | static const byte PADDING[64]; /* padding for calculate */ 54 | static const char HEX[16]; 55 | enum { BUFFER_SIZE = 1024 }; 56 | }; 57 | 58 | #endif /*MD5_H*/ 59 | 60 | -------------------------------------------------------------------------------- /CloudPan1.0/server/ser: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qinyuLT/CloudPan/65cdb6220ab26d43cca368cc5423bca2df1f040d/CloudPan1.0/server/ser -------------------------------------------------------------------------------- /CloudPan1.0/server/serLog.out: -------------------------------------------------------------------------------- 1 | nohup: 忽略输入 2 |  3 | =============== Service ================ 4 | EPOLL:Received New Connection Request 5 | confd=5 ip=127.0.0.1 port=54158 6 | ======================================== 7 | Start do_service 8 | 9 | =============== Service ================ 10 | EPOLL:Received New Connection Request 11 | confd=5 ip=127.0.0.1 port=54161 12 | ======================================== 13 | Start do_service 14 | 0 push_back 15 | 16 | Save key: bbb data: e10adc3949ba59abbe56e057f20f883e 17 | End of do_service 18 | ======================================== 19 | -------------------------------------------------------------------------------- /CloudPan1.0/server/sqlConnPool.cpp: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | > File Name: sqlConnPool.cpp 3 | > Author: qinyu 4 | > Mail: qinyu.LT@gmail.com 5 | > Created Time: 2016年04月23日 星期六 15时02分26秒 6 | ************************************************************************/ 7 | #include "sql_conn_pool.h" 8 | #include 9 | #include 10 | #include 11 | 12 | using namespace std; 13 | using namespace sql; 14 | 15 | CSqlConnPool::CSqlConnPool() 16 | { 17 | driver_ = NULL; 18 | DBName_ = NULL; 19 | } 20 | 21 | CSqlConnPool::~CSqlConnPool() 22 | { 23 | Destroy(); 24 | } 25 | 26 | void CSqlConnPool::Init(const SqlConnInfo& sqlConnInfo) 27 | { 28 | sqlConnInfo_ = sqlConnInfo; 29 | 30 | try 31 | { 32 | this->driver_ = get_driver_instance(); 33 | } 34 | catch (sql::SQLException &e) 35 | { 36 | cout<<"CSqlConnPool::Init:SQLException" << e.what()<CreateConnection(); 46 | if (conn) 47 | { 48 | queue_conn_.push_back(conn); 49 | } 50 | else 51 | { 52 | cout<<"CSqlConnPool::Init:connection failed! index = " << i<::iterator pos = queue_conn_.begin(); pos != queue_conn_.end(); ++pos) 66 | { 67 | this->TerminateConnection(*pos); 68 | } 69 | queue_conn_.clear(); 70 | } 71 | 72 | sql::Connection * CSqlConnPool::CreateConnection() 73 | { 74 | sql::Connection *conn = NULL; 75 | try 76 | { 77 | std::string url = string("tcp://") + sqlConnInfo_.ip + string(":") + sqlConnInfo_.port; 78 | conn = driver_->connect(url.c_str(), sqlConnInfo_.user_name.c_str(), sqlConnInfo_.password.c_str()); 79 | //cout<<"CSqlConnPool::CreateConnection:Create one new connection."< lock(mutex_); 114 | 115 | if (!queue_conn_.empty()) 116 | { 117 | conn = queue_conn_.front(); 118 | queue_conn_.pop_front(); 119 | } 120 | 121 | /* 如果连接不是空指针,先判断是否已经失效(8小时未用失效问题)*/ 122 | if (conn) 123 | { 124 | if (!this->IsValidConnection(conn)) 125 | { 126 | this->TerminateConnection(conn); 127 | } 128 | } 129 | 130 | if (conn == NULL) 131 | { 132 | conn = this->CreateConnection(); 133 | if(conn != NULL) 134 | { 135 | conn->setSchema(DBName_); 136 | } 137 | } 138 | 139 | return conn; 140 | } 141 | 142 | void CSqlConnPool::ReleaseConnection(sql::Connection * conn) 143 | { 144 | if (conn) 145 | { 146 | boost::unique_lock lock(mutex_); 147 | bool found = false; 148 | for (deque::iterator pos = queue_conn_.begin(); pos != queue_conn_.end(); ++pos) 149 | { 150 | if (*pos == conn) 151 | { 152 | found = true; 153 | break; 154 | } 155 | } 156 | if (!found) 157 | { 158 | queue_conn_.push_back(conn); 159 | } 160 | } 161 | } 162 | 163 | /* 判断连接是否有效(为了解决8小时连接失效问题) */ 164 | bool CSqlConnPool::IsValidConnection(sql::Connection *conn) 165 | { 166 | bool ret = true; 167 | try 168 | { 169 | conn->setSchema(DBName_); 170 | } 171 | catch (...) 172 | { 173 | ret = false; 174 | } 175 | return ret; 176 | } 177 | 178 | /* 179 | int main() 180 | { 181 | const SqlConnInfo conInfo={10,"127.0.0.1","3306","root","qinyu"}; 182 | 183 | CSqlConnPool pool; 184 | pool.Init(conInfo); 185 | pool.SetDBName("FTP"); 186 | 187 | Connection *conn; 188 | Statement *state; 189 | ResultSet *result; 190 | //MYSQL *result; 191 | 192 | conn=pool.GetConnection(); 193 | state = conn->createStatement(); 194 | state->execute("use FTP"); 195 | result = state->executeQuery("select *from user"); 196 | size_t i = result->rowsCount(); 197 | cout<findColumn("password")<next()) 200 | { 201 | //cout<getCursorName()<<" "; 202 | string name=result->getString("user_id"); 203 | string password=result->getString("password"); 204 | int i=result->getInt("friends_id"); 205 | int j=result->getInt("file_id"); 206 | cout<getRow()<<":"<setAutoCommit(0); 210 | //cout<<"DataBae model:"<getAutoCommit()< File Name: sql_conn_pool.h 3 | > Author: qinyu 4 | > Mail: qinyu.LT@gmail.com 5 | > Created Time: 2016年04月23日 星期六 15时02分26秒 6 | ************************************************************************/ 7 | #ifndef CONN_POOL_H 8 | #define CONN_POOL_H 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include "mysql/mysql.h" 20 | using namespace std; 21 | 22 | typedef struct sqlConnInfo_ 23 | { 24 | int max_conn_num; 25 | std::string ip; 26 | std::string port; 27 | std::string user_name; 28 | std::string password; 29 | } SqlConnInfo; 30 | 31 | class CSqlConnPool 32 | { 33 | public: 34 | CSqlConnPool(); 35 | ~CSqlConnPool(); 36 | 37 | void Init(const SqlConnInfo& sqlConnInfo); 38 | void Destroy(); 39 | 40 | void SetDBName(const char* DBName); 41 | 42 | sql::Connection*GetConnection(); 43 | void ReleaseConnection(sql::Connection * conn); 44 | 45 | private: 46 | 47 | SqlConnInfo sqlConnInfo_; 48 | 49 | boost::mutex mutex_; 50 | sql::Driver* driver_; 51 | const char* DBName_; 52 | deque queue_conn_; 53 | 54 | sql::Connection * CreateConnection(); 55 | void TerminateConnection(sql::Connection * conn); 56 | bool IsValidConnection(sql::Connection *conn); //判断数据库连接是否有效(为了解决8小时连接失效问题) 57 | }; 58 | 59 | #endif 60 | -------------------------------------------------------------------------------- /CloudPan1.0/server/tPool.cpp: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | > File Name: tPool.cpp 3 | > Author: qinyu 4 | > Mail: qinyu.LT@gmail.com 5 | > Created Time: 2016年04月24日 星期日 17时10分01秒 6 | ************************************************************************/ 7 | #include "tPool.h" 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | //#include 15 | //using namespace std; 16 | 17 | /* 18 | //任务节点 19 | typedef struct tpool_work 20 | { 21 | void * (*routine)(void*);//任务函数 22 | void *arg; //传入任务函数的参数 23 | struct tpool_work *next; 24 | }tpool_work_t; 25 | 26 | typedef struct tpool 27 | { 28 | int shudown; //线程池是否销毁 29 | int max_thr_num; //最大线程数 30 | pthread_t *thr_id; //线程ID组数 31 | tpool_work_t *queue_head; 32 | tpool_work_t *queue_tail; 33 | pthread_mutex_t queue_lock; 34 | pthread_cond_t queue_ready; 35 | }tpool_t; 36 | */ 37 | static tpool_t *tpool = NULL; 38 | 39 | //工作线程函数,从任务链表取出任务并执行 40 | static void *thread_routine(void *arg) 41 | { 42 | tpool_work_t *work; 43 | 44 | while(1) 45 | { 46 | //任务列表为空 且 线程池未关闭:线程阻塞等待任务 47 | pthread_mutex_lock(&tpool->queue_lock); 48 | while(!tpool->queue_head && !tpool->shudown) 49 | { 50 | pthread_cond_wait(&tpool->queue_ready,&tpool->queue_lock); 51 | } 52 | 53 | //如果线程池关闭,退出 54 | if(tpool->shudown) 55 | { 56 | pthread_mutex_unlock(&tpool->queue_lock); 57 | pthread_exit(NULL); 58 | } 59 | 60 | //从任务列表取任务并执行 61 | work = tpool->queue_head; 62 | tpool->queue_head = tpool->queue_head->next; 63 | pthread_mutex_unlock(&tpool->queue_lock); 64 | work->routine(work->arg); 65 | 66 | //线程完成,释放任务 67 | free(work->arg); 68 | free(work); 69 | } 70 | 71 | return NULL; 72 | } 73 | 74 | //创建线程池 75 | int createPool(int max_thr_num) 76 | { 77 | int i; 78 | tpool = (tpool_t*)calloc(1,sizeof(tpool_t)); 79 | if(!tpool) 80 | { 81 | printf("%s: calloc tpool failed\n",__FUNCTION__); 82 | exit(1); 83 | } 84 | 85 | //初始化任务链表,互斥量,条件变量 86 | tpool->max_thr_num = max_thr_num; 87 | tpool->shudown = 0; 88 | tpool->queue_head = NULL; 89 | tpool->queue_tail = NULL; 90 | if(pthread_mutex_init(&tpool->queue_lock,NULL) != 0) 91 | { 92 | printf("%s :pthread_mutex_init failed,errno:%d,errno:%s\n",__FUNCTION__,errno,strerror(errno)); 93 | exit(-1); 94 | } 95 | 96 | if(pthread_cond_init(&tpool->queue_ready,NULL) != 0) 97 | { 98 | printf("%s:pthread_cond_init failed,errno:%d,errno:%s\n",__FUNCTION__,errno,strerror(errno)); 99 | exit(-1); 100 | } 101 | 102 | //创建工作线程 103 | tpool->thr_id = (pthread_t*)calloc(max_thr_num,sizeof(pthread_t)); 104 | if(!tpool->thr_id) 105 | { 106 | printf("%s:calloc thr_id failed\n",__FUNCTION__); 107 | exit(1); 108 | } 109 | 110 | for(i=0;ithr_id[i],NULL,thread_routine,NULL) != 0) 113 | { 114 | printf("%s:pthread_create failed,errno:%d,errno:%s\n",__FUNCTION__,errno,strerror(errno)); 115 | exit(-1); 116 | } 117 | } 118 | return 0; 119 | } 120 | 121 | //销毁线程池 122 | void destroyPool() 123 | { 124 | int i; 125 | tpool_work_t *member; 126 | if(tpool->shudown)return; 127 | 128 | //关闭线程池开关 129 | tpool->shudown = 1; 130 | 131 | //唤醒所以阻塞的线程 132 | pthread_mutex_lock(&tpool->queue_lock); 133 | pthread_cond_broadcast(&tpool->queue_ready); 134 | pthread_mutex_unlock(&tpool->queue_lock); 135 | 136 | //回收结束线程的剩余资源 137 | for(i=0;imax_thr_num;++i) 138 | { 139 | pthread_join(tpool->thr_id[i],NULL); 140 | } 141 | 142 | //释放threadID数组 143 | free(tpool->thr_id); 144 | 145 | //释放未完成的任务 146 | while(tpool->queue_head) 147 | { 148 | member = tpool->queue_head; 149 | tpool->queue_head = tpool->queue_head->next; 150 | free(member->arg); 151 | free(member); 152 | } 153 | 154 | //销毁互斥量,条件变量 155 | pthread_mutex_destroy(&tpool->queue_lock); 156 | pthread_cond_destroy(&tpool->queue_ready); 157 | 158 | //释放线程池结构体 159 | free(tpool); 160 | } 161 | 162 | //向线程池添加任务 163 | int addWorkToPool(void*(*routine)(void*),void *arg) 164 | { 165 | tpool_work_t *work; 166 | 167 | if(!routine) 168 | { 169 | printf("%s:Invalid argument\n",__FUNCTION__); 170 | return -1; 171 | } 172 | 173 | //work指向等待加入任务链表的任务 174 | work = (tpool_work_t*)malloc(sizeof(tpool_work_t)); 175 | if(!work) 176 | { 177 | printf("%s:malloc failed\n",__FUNCTION__); 178 | return -1; 179 | } 180 | work->routine = routine; 181 | work->arg = arg; 182 | work->next = NULL; 183 | 184 | //将任务节点添加到任务链表 185 | pthread_mutex_lock(&tpool->queue_lock); 186 | if(!tpool->queue_head) 187 | { 188 | tpool->queue_head = work; 189 | tpool->queue_tail = work; 190 | } 191 | else 192 | { 193 | tpool->queue_tail->next = work; 194 | tpool->queue_tail = work; 195 | } 196 | 197 | //通知工作线程,有新任务添加 198 | pthread_cond_signal(&tpool->queue_ready); 199 | pthread_mutex_unlock(&tpool->queue_lock); 200 | return 0; 201 | } 202 | /* 203 | int main() 204 | { 205 | if(createPool(4)) 206 | { 207 | printf("thread pool create failed!\n"); 208 | exit(-1); 209 | } 210 | printf("-- Thread Pool Strart --\n"); 211 | 212 | return 0; 213 | }*/ 214 | -------------------------------------------------------------------------------- /CloudPan1.0/server/tPool.h: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | > File Name: tPool.h 3 | > Author: qinyu 4 | > Mail: qinyu.LT@gmail.com 5 | > Created Time: 2016年04月24日 星期日 16时53分08秒 6 | ************************************************************************/ 7 | #ifndef THREAD_POOL_H 8 | #define THREAD_POOL_H 9 | 10 | #include 11 | 12 | //任务节点 13 | typedef struct tpool_work 14 | { 15 | void * (*routine)(void*);//任务函数 16 | void *arg; //传入任务函数的参数 17 | struct tpool_work *next; 18 | }tpool_work_t; 19 | 20 | typedef struct tpool 21 | { 22 | int shudown; //线程池是否销毁 23 | int max_thr_num; //最大线程数 24 | pthread_t *thr_id; //线程ID组数 25 | tpool_work_t *queue_head; 26 | tpool_work_t *queue_tail; 27 | pthread_mutex_t queue_lock; 28 | pthread_cond_t queue_ready; 29 | }tpool_t; 30 | 31 | //创建线程池 32 | int createPool(int max_thr_num); 33 | //销毁线程池 34 | void destroyPool(); 35 | //向线程池添加任务 36 | int addWorkToPool(void*(*routine)(void*),void *arg); 37 | 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /CloudPan1.0/server/testser.cpp: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | > File Name: testser.cpp 3 | > Author: qinyu 4 | > Mail: qinyu.LT@gmail.com 5 | > Created Time: 2016年04月19日 星期二 23时11分23秒 6 | ************************************************************************/ 7 | #include "conSer.h" 8 | #include "MyDB.h" 9 | #include 10 | using namespace std; 11 | 12 | void do_cmd() 13 | { 14 | //ser.sql.p 15 | int select = 1;//atoi(cmd); 16 | 17 | switch(select) 18 | { 19 | case ENTER: 20 | //cout<::iterator it; 48 | for(it=ser.sql.begin();it!=ser.sql.end();++it) 49 | { 50 | cout<<*it<<" "; 51 | } 52 | cout< File Name: mysql.cpp 3 | > Author: qinyu 4 | > Mail: qinyu.LT@gmail.com 5 | > Created Time: 2016年04月19日 星期二 23时10分07秒 6 | ************************************************************************/ 7 | 8 | #include "mysql.h" 9 | #include 10 | using namespace std; 11 | 12 | MyDB::MyDB() 13 | { 14 | connection = mysql_init(NULL); 15 | if(connection == NULL) 16 | { 17 | cout<<"Errorr"< File Name: xcp.c 3 | > Author: qinyu 4 | > Mail: qinyu.LT@gmail.com 5 | > Created Time: 2016年06月12日 星期日 16时26分56秒 6 | ************************************************************************/ 7 | 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 | #define _FILE_OFFSET_BITS 64 22 | #define BOOL int 23 | #define TRUE 1 24 | #define FALSE 0 25 | #define MAX_FMTSTR_LENGTH 2048 26 | #define COPY_BUF_SIZE 4096 27 | #define MAX_PATH_LENGTH(PATH_MAX + 1) 28 | #define GBYTES(1024 * 1024 *1024) 29 | #define KBYTES(1024 * 1024) 30 | #define HOUR (60 * 60) 31 | #define MINUTE 60 32 | #define OPP_CONTINUE 0 33 | #define OPP_SKIP 1 34 | #define OPP_CANCEL 2 35 | 36 | #define MSGT_PROMPT 0 37 | #define MSGT_WARNING 1 38 | #define MSGT_ERROR 2 39 | #define MSGT_VERBOSE 3 40 | #define MSGT_DEMO 4 41 | 42 | typedef int (*each_opp_t)(const char*,const char*,const char*,const struct stat* st); 43 | typedef void (*sig_handler_t)(int); 44 | 45 | int sum_file = 0; 46 | int sum_dir = 0; 47 | long long sum_size = 0; 48 | int copied_file = 0; 49 | int copied_dir = 0; 50 | long long copied_size = 0; 51 | time_t copy_start_time = 0; 52 | BOOL status_pause = FALSE; 53 | BOOL opt_d = FALSE; 54 | BOOL opt_f = FALSE; 55 | BOOL opt_q = FALSE; 56 | BOOL opt_r = FALSE; 57 | BOOL opt_v = FALSE; 58 | 59 | int action(const char *path_from,const char *path_to,const char *path_tree,const struct stat* st) 60 | { 61 | int ret_val = OPP_CONTINUE; 62 | char path_from_full[MAX_PATH_LENGTH]; 63 | char path_to_full[MAX_PATH_LENGTH]; 64 | size_t rd,wr,swr; 65 | char buf[COPY_BUF_SIZE]; 66 | FILE *src_file,*dest_file; 67 | BOOL over_write = FALSE; 68 | int cmd; 69 | BOOL skip = FALSE; 70 | struct stat st_dest; 71 | 72 | make_path(path_from_full,path_from,path_tree); 73 | make_path(path_to_full,path_to,path_tree); 74 | 75 | if(S_ISREG(st->st_mode)) 76 | { 77 | if(opt_v) 78 | { 79 | printf_message(MSGT_VERBOSE,"cp \"%s\" -> \"%s\". \n",path_from_full,path_to_full); 80 | } 81 | 82 | if(strcmp(path_from_full,path_to_full) == 0) 83 | { 84 | ret_val = OPP_SKIP; 85 | } 86 | } 87 | } 88 | 89 | void usage() 90 | { 91 | printf("xcp :\n"); 92 | 93 | printf("description:cp with progress\n"); 94 | printf("synopsis: xcp [OPTIONS] src1 [src2 ... srcn] dest\n\n"); 95 | printf("[OPTIONS]\n"); 96 | printf("-r:recusive copy sub directories.\n"); 97 | printf("-f:force overwrite without prompt.\n"); 98 | printf("-q:quiet no warning/error message.\n"); 99 | printf("-d:demo,do not copy,output message only.\n"); 100 | printf("-v:verbos output.\n"); 101 | printf("-h:show usage message.\n"); 102 | } 103 | 104 | BOOL is_self_copy(const char* src,const char* dest) 105 | { 106 | char c; 107 | char *sub = strstr(dest,src); 108 | 109 | if(sub) 110 | { 111 | c = sub[strlen(src)]; 112 | return c=='\0' || c=='/' || src[strlen(src) -1]=='/'; 113 | } 114 | else 115 | { 116 | return FALSE; 117 | } 118 | } 119 | 120 | int main(int argc,char *args[]) 121 | { 122 | int i = 0; 123 | char *path_from=NULL,*path_to=NULL,*file_name=NULL; 124 | char *path_to_fixed[MAX_PATH_LENGTH]; 125 | struct stat st_src,st_dest; 126 | char human_readal_size[200]; 127 | int opt; 128 | BOOL help = FALSE; 129 | 130 | while((opt=getopt(argc,args,"rfqdhv")) != -1) 131 | { 132 | switch(opt) 133 | { 134 | case 'r': 135 | opt_r = TRUE; 136 | break; 137 | case 'f': 138 | opt_r = TRUE; 139 | break; 140 | case 'q': 141 | opt_q = TRUE; 142 | break; 143 | case 'd': 144 | opt_d = TRUE; 145 | break; 146 | case 'h': 147 | help = TRUE; 148 | break; 149 | case 'v': 150 | opt_v = TRUE; 151 | break; 152 | case '?': 153 | printf("unknown option:%c\n",optopt); 154 | break; 155 | default: 156 | break; 157 | } 158 | } 159 | 160 | if(help || optind+2 > argc) 161 | { 162 | usage(); 163 | return 1; 164 | } 165 | 166 | sum_file = 0; 167 | sum_dir = 0; 168 | sum_size = 0; 169 | 170 | time(copy_start_time); 171 | show_status(FALSE); 172 | install_timer(1,time_handler): 173 | 174 | for(i=optind;i \"%s\"\n",path_from,path_to); 196 | continue; 197 | } 198 | } 199 | else 200 | { 201 | printf_message(MSGT_WARNING,"skip \"%s\" not a file nor a directory.\n",path_from); 202 | continue; 203 | } 204 | 205 | if(opt_d) 206 | { 207 | walk(path_from,path_to,NULL,demo); 208 | } 209 | else 210 | { 211 | walk(path_from,path_to,NULL,action); 212 | } 213 | } 214 | install_timer(0,NULL); 215 | show_status(TRUE); 216 | 217 | return 0; 218 | } 219 | 220 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CloudPan 2 | ##version 1.0 3 | ####系统架构图 4 | 5 | ![](https://github.com/qinyuLT/Images/blob/master/cloudpan.png)
6 | 7 | ###负载均衡服务器的作用: 8 | - 1.接收Cli端客户请求消息Request Msg,并作相应处理,回传Respone Msg; 9 | - 2.负载均衡服务器负责客户的登录、注册功能; 10 | - 3.负载均衡服务器管理后端的功能处理服务器(FileTransServer、ChartServer),选择合适服务器处理业务 11 | 12 | ###FileTransServer: 13 | - 负责文件处理相关的操作 14 | 15 | ###ChartServer 16 | - 负责聊天相关的操作 17 | 18 | ##version 2.0 19 | 相对version1.0版本的改进是:使用[G6](http://www.oschina.net/p/G6)开源负载均衡器,并加入相应的进程池、连接池;
20 | 21 | 该项目是在linux下采用C/C++编程,基于TCP协议,服务器端采用多进程长连接的socket的通信方式,并采用开源的负载均衡器G6作为客户端请求与服务端响应的中间件分发器,[G6](http://www.oschina.net/p/G6)是该开发者在[G5](http://www.oschina.net/p/g5)的基础上的升级版,相比G5多了心跳报告和命令管理的功能,所以对于服务器的状态就不需要关心了,包括服务器的组装,只需要修改G6的配置文件。考虑到服务器端如果每接收到一个请求fork一个进程处理方式的效率低,所以服务器端采用进程池方式,结合[libevent](http://libevent.org/)网络库,可以处理并发的TCP连接请求,同时对数据库的访问会带来同样的问题,所以实现了一个基于[mysqlclient](https://pypi.python.org/pypi/mysqlclient)接口的连接池。 22 | 23 | ###一共使用三个端口:[详情 public.h](https://github.com/qinyuLT/CloudPan/blob/master/CloudPan1.0/public.h) 24 | ```c++ 25 | #define CPT 6666 //管理端口 26 | #define TPT 6667 //传输端口 27 | #define MPT 6668 //聊天端口 28 | ``` 29 | ###数据的处理 30 | [memcached](http://php.net/manual/zh/book.memcached.php)的采用是为了减轻对mysql数据库的访问,比如在用户注册的时候,需要插入mysql中并在memcached中基于key-value的键值对用户名和密码进行存储,这样对于用户之后的登录只需要在memcached中查询,而不需要访问数据库,因memcached是基于内存的缓存系统,所以在这样查询效率就会很高,但是不好的一点就是如果系统宕机或者重启,数据就没有了;对于这种情况我的处理方式是,定期将memcached中的数据写入硬盘文件,每次重启导入该文件,这里的定期采用的是libevent中统一事件源中的定时器事件。 31 | 32 | memchache和mysql对于文件的存储,只存储文件在磁盘上的地址。对于用户密码的安全性已经文件的一致性,采用了MD5算法,客户端发送的密码是经过MD5算法生成的32位随机字符串,对于文件,这32位字符串可以唯一标识,用它可以实现秒传功能,即便是相同内容的不同文件名也可以分辨出来。 33 | 34 | 断点续传功能的实现跟大文件的传输有关,对小文件一次传输不作记录;对于大文件的传输采用两个结构体:分别传输文件头部信息和文件数据内容 35 | ```c++ 36 | //文件头部信息 37 | struct fileinfo 38 | { 39 | string file_name; //文件名 40 | string file_MD5; //文件MD5值 41 | string file_path; //文件存储路径 42 | int file_size; //文件大小 43 | int file_chunk_size; //分块个数 44 | int chunk_size; //分块标准 45 | bool trans_status; //传输状态 46 | }; 47 | //文件内容 48 | struct filedata 49 | { 50 | string file_name; //文件名 51 | int id; //分块id 52 | int offset; //该块在文件的偏移量 53 | bool trans_status; //传输状态 54 | }; 55 | ``` 56 | 57 | ###linux下常用的文件传输方式: 58 | - FTP: ftp 主机名 /ip 常用命令:ls,cd,get,put,open
59 | 使用ftp脚本可以自动完成文件传输任务(堆积命令)
60 | 不保留文件的属性(文档的保护模式或者修改次数),不能递归的拷贝子目录
61 | 62 | - rcp: 63 | 保留文件的属性(-p),可以递归的拷贝子目录(-r),提供DES加密传输(-x)
64 | 65 | - scp: secure copy 66 | 安全拷贝的缩写,使用ssh来传输数据,并使用与ssh相同的认证模式
67 | scp命令用法和rcp命令用法非常类似,但是scp更安全
68 | 69 | - wget: 支持HTTP、HTTPS、FTP协议,支持代理服务器以及断点续传功能
70 | 可以实现递归下载
71 | 72 | - curl: 是对libcurl库的一个命令行工具包,功能很强大,80多个下载参数
73 | 支持FTP、FTPS、HTTP、HTTPS、TFTP、SFTP、TELNET等各种协议
74 | 支持代理、用户认证、FTP传输、HTTP post、SSL连接、文件续传等
75 | 76 | - rsync:高效的远程数据备份和镜像工具、可以快速同步多台主机间的文件
77 | 支持文件详细属性的拷贝(所有者、组信息、权限信息等)
78 | 通过远程shell(ssh/rsh)进程传输
79 | 流水线式文件传输模式,文件传输效率高
80 | 81 | rsync算法能在相当短的时间内计算出需要备份的数据
82 | 只对源、目的文件的不同进行传输
83 | 从而降低网络中传输的数据量,以此达到快速备份镜像的目的
84 | 85 | --------------------------------------------------------------------------------