├── README.md ├── tools ├── c │ ├── .swp │ ├── .migtable.cpp.swp │ ├── _tools.h │ ├── _tools_oracle.h │ ├── procctl.cpp │ ├── deletefiles.cpp │ ├── gzipfiles.cpp │ ├── execsql.cpp │ └── checkproc.cpp └── ini │ └── xmltodb.xml ├── public ├── libftp.a ├── libftp.so ├── lib_public.a ├── socket │ ├── .swp │ ├── client │ ├── demo01 │ ├── demo02 │ ├── demo03 │ ├── demo04 │ ├── demo05 │ ├── demo06 │ ├── demo07 │ ├── demo08 │ ├── demo10 │ ├── demo11 │ ├── demo12 │ ├── demo13 │ ├── demo14 │ ├── demo20 │ ├── demo26 │ ├── demo27 │ ├── demo28 │ ├── demo31 │ ├── demo32 │ ├── demo33 │ ├── tcpepoll │ ├── tcppoll │ ├── tcpselect │ ├── demo07.cpp │ ├── demo27.cpp │ ├── demo08.cpp │ ├── demo32.cpp │ ├── demo31.cpp │ ├── demo05.cpp │ ├── demo33.cpp │ ├── client.cpp │ ├── demo03.cpp │ ├── demo06.cpp │ ├── demo01.cpp │ ├── demo04.cpp │ ├── demo26.cpp │ ├── demo11.cpp │ ├── demo02.cpp │ ├── makefile │ ├── demo10.cpp │ ├── demo13.cpp │ ├── demo20.cpp │ └── tcpepoll.cpp ├── db │ ├── mysql │ │ ├── .swp │ │ ├── 1.jpg │ │ ├── 2.jpg │ │ ├── 1_out.jpg │ │ ├── 2_out.jpg │ │ ├── deletetable.cpp │ │ ├── makefile │ │ ├── filetoblob.cpp │ │ ├── blobtofile.cpp │ │ ├── createtable.cpp │ │ ├── updatetable.cpp │ │ ├── selecttable.cpp │ │ └── inserttable.cpp │ ├── oracle │ │ ├── memo_in.txt │ │ ├── pic_in.jpeg │ │ ├── pic_out.jpeg │ │ ├── tmp.sh │ │ ├── deletetable.cpp │ │ ├── blobtofile.cpp │ │ ├── clobtofile.cpp │ │ ├── counttable.cpp │ │ ├── createtable.cpp │ │ ├── updatetable.cpp │ │ ├── execplsql.cpp │ │ ├── filetoclob.cpp │ │ ├── filetoblob.cpp │ │ ├── inserttable.cpp │ │ ├── selecttable.cpp │ │ └── makefile │ └── postgresql │ │ ├── deletetable.cpp │ │ ├── counttable.cpp │ │ ├── createtable.cpp │ │ ├── makefile │ │ ├── updatetable.cpp │ │ ├── inserttable.cpp │ │ └── selecttable.cpp ├── ini │ ├── hssms.ini │ └── hssms.xml ├── lib_public.so ├── demo │ ├── demo30.cpp │ ├── demo7.cpp │ ├── demo1.cpp │ ├── demo4.cpp │ ├── demo29.cpp │ ├── demo28.cpp │ ├── demo32.cpp │ ├── demo8.cpp │ ├── demo24.cpp │ ├── demo26.cpp │ ├── demo2.cpp │ ├── demo18.cpp │ ├── demo16.cpp │ ├── demo10.cpp │ ├── demo43.cpp │ ├── demo37.cpp │ ├── demo36.cpp │ ├── demo5.cpp │ ├── demo12.cpp │ ├── demo51.cpp │ ├── demo47.cpp │ ├── demo48.cpp │ ├── demo40.cpp │ ├── demo52.cpp │ ├── demo50.cpp │ ├── demo34.cpp │ ├── demo22.cpp │ ├── demo20.cpp │ ├── demo39.cpp │ ├── demo42.cpp │ ├── demo21.cpp │ ├── demo45.cpp │ └── makefile ├── makefile ├── _cmpublic.h └── _ftp.h ├── idc1 ├── bin │ └── crtsurfdata4 └── ini │ └── xmltodb.xml ├── myIdc ├── bin │ ├── crtsurfdata1 │ └── crtsurfdata2 └── c │ ├── makefile │ ├── crtsurfdata1.cpp │ └── crtsurfdata2.cpp ├── idc ├── c │ ├── .obtcodetodb.cpp.swp │ ├── killall.sh │ ├── rc.local │ ├── crtsurfdata1.cpp │ ├── idcapp.h │ ├── makefile │ ├── obtmindtodb1.cpp │ ├── crtsurfdata2.cpp │ ├── obtmindtodb5.cpp │ └── obtmindtodb.cpp ├── sql │ ├── T_USERANDINTER.sql │ ├── T_USERINFO.sql │ ├── cleardata.sql │ ├── T_DATATYPE.sql │ └── T_INTERCFG.sql └── ini │ └── xmltodb.xml ├── pthread ├── book10.cpp ├── book9.cpp ├── book4.cpp ├── book11.cpp ├── book16.cpp ├── book5.cpp ├── book13.cpp ├── book7.cpp ├── book12.cpp ├── book1.cpp ├── book6.cpp ├── book15.cpp ├── book8.cpp ├── makefile ├── book14.cpp ├── book17.cpp ├── book2.cpp ├── book3.cpp ├── book19.cpp └── book18.cpp └── trebox ├── _cmpublic.h └── CLogFile.cpp /README.md: -------------------------------------------------------------------------------- 1 | # Meteorological-data-processing-project 2 | 3 | C/C++气象数据中心实战项目学习 4 | -------------------------------------------------------------------------------- /tools/c/.swp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuozhudd/Meteorological-data-processing-project/HEAD/tools/c/.swp -------------------------------------------------------------------------------- /public/libftp.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuozhudd/Meteorological-data-processing-project/HEAD/public/libftp.a -------------------------------------------------------------------------------- /public/libftp.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuozhudd/Meteorological-data-processing-project/HEAD/public/libftp.so -------------------------------------------------------------------------------- /public/lib_public.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuozhudd/Meteorological-data-processing-project/HEAD/public/lib_public.a -------------------------------------------------------------------------------- /public/socket/.swp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuozhudd/Meteorological-data-processing-project/HEAD/public/socket/.swp -------------------------------------------------------------------------------- /idc1/bin/crtsurfdata4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuozhudd/Meteorological-data-processing-project/HEAD/idc1/bin/crtsurfdata4 -------------------------------------------------------------------------------- /myIdc/bin/crtsurfdata1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuozhudd/Meteorological-data-processing-project/HEAD/myIdc/bin/crtsurfdata1 -------------------------------------------------------------------------------- /myIdc/bin/crtsurfdata2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuozhudd/Meteorological-data-processing-project/HEAD/myIdc/bin/crtsurfdata2 -------------------------------------------------------------------------------- /public/db/mysql/.swp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuozhudd/Meteorological-data-processing-project/HEAD/public/db/mysql/.swp -------------------------------------------------------------------------------- /public/db/mysql/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuozhudd/Meteorological-data-processing-project/HEAD/public/db/mysql/1.jpg -------------------------------------------------------------------------------- /public/db/mysql/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuozhudd/Meteorological-data-processing-project/HEAD/public/db/mysql/2.jpg -------------------------------------------------------------------------------- /public/ini/hssms.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuozhudd/Meteorological-data-processing-project/HEAD/public/ini/hssms.ini -------------------------------------------------------------------------------- /public/ini/hssms.xml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuozhudd/Meteorological-data-processing-project/HEAD/public/ini/hssms.xml -------------------------------------------------------------------------------- /public/lib_public.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuozhudd/Meteorological-data-processing-project/HEAD/public/lib_public.so -------------------------------------------------------------------------------- /public/socket/client: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuozhudd/Meteorological-data-processing-project/HEAD/public/socket/client -------------------------------------------------------------------------------- /public/socket/demo01: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuozhudd/Meteorological-data-processing-project/HEAD/public/socket/demo01 -------------------------------------------------------------------------------- /public/socket/demo02: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuozhudd/Meteorological-data-processing-project/HEAD/public/socket/demo02 -------------------------------------------------------------------------------- /public/socket/demo03: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuozhudd/Meteorological-data-processing-project/HEAD/public/socket/demo03 -------------------------------------------------------------------------------- /public/socket/demo04: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuozhudd/Meteorological-data-processing-project/HEAD/public/socket/demo04 -------------------------------------------------------------------------------- /public/socket/demo05: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuozhudd/Meteorological-data-processing-project/HEAD/public/socket/demo05 -------------------------------------------------------------------------------- /public/socket/demo06: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuozhudd/Meteorological-data-processing-project/HEAD/public/socket/demo06 -------------------------------------------------------------------------------- /public/socket/demo07: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuozhudd/Meteorological-data-processing-project/HEAD/public/socket/demo07 -------------------------------------------------------------------------------- /public/socket/demo08: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuozhudd/Meteorological-data-processing-project/HEAD/public/socket/demo08 -------------------------------------------------------------------------------- /public/socket/demo10: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuozhudd/Meteorological-data-processing-project/HEAD/public/socket/demo10 -------------------------------------------------------------------------------- /public/socket/demo11: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuozhudd/Meteorological-data-processing-project/HEAD/public/socket/demo11 -------------------------------------------------------------------------------- /public/socket/demo12: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuozhudd/Meteorological-data-processing-project/HEAD/public/socket/demo12 -------------------------------------------------------------------------------- /public/socket/demo13: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuozhudd/Meteorological-data-processing-project/HEAD/public/socket/demo13 -------------------------------------------------------------------------------- /public/socket/demo14: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuozhudd/Meteorological-data-processing-project/HEAD/public/socket/demo14 -------------------------------------------------------------------------------- /public/socket/demo20: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuozhudd/Meteorological-data-processing-project/HEAD/public/socket/demo20 -------------------------------------------------------------------------------- /public/socket/demo26: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuozhudd/Meteorological-data-processing-project/HEAD/public/socket/demo26 -------------------------------------------------------------------------------- /public/socket/demo27: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuozhudd/Meteorological-data-processing-project/HEAD/public/socket/demo27 -------------------------------------------------------------------------------- /public/socket/demo28: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuozhudd/Meteorological-data-processing-project/HEAD/public/socket/demo28 -------------------------------------------------------------------------------- /public/socket/demo31: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuozhudd/Meteorological-data-processing-project/HEAD/public/socket/demo31 -------------------------------------------------------------------------------- /public/socket/demo32: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuozhudd/Meteorological-data-processing-project/HEAD/public/socket/demo32 -------------------------------------------------------------------------------- /public/socket/demo33: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuozhudd/Meteorological-data-processing-project/HEAD/public/socket/demo33 -------------------------------------------------------------------------------- /public/socket/tcpepoll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuozhudd/Meteorological-data-processing-project/HEAD/public/socket/tcpepoll -------------------------------------------------------------------------------- /public/socket/tcppoll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuozhudd/Meteorological-data-processing-project/HEAD/public/socket/tcppoll -------------------------------------------------------------------------------- /public/socket/tcpselect: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuozhudd/Meteorological-data-processing-project/HEAD/public/socket/tcpselect -------------------------------------------------------------------------------- /idc/c/.obtcodetodb.cpp.swp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuozhudd/Meteorological-data-processing-project/HEAD/idc/c/.obtcodetodb.cpp.swp -------------------------------------------------------------------------------- /public/db/mysql/1_out.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuozhudd/Meteorological-data-processing-project/HEAD/public/db/mysql/1_out.jpg -------------------------------------------------------------------------------- /public/db/mysql/2_out.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuozhudd/Meteorological-data-processing-project/HEAD/public/db/mysql/2_out.jpg -------------------------------------------------------------------------------- /tools/c/.migtable.cpp.swp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuozhudd/Meteorological-data-processing-project/HEAD/tools/c/.migtable.cpp.swp -------------------------------------------------------------------------------- /public/db/oracle/memo_in.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuozhudd/Meteorological-data-processing-project/HEAD/public/db/oracle/memo_in.txt -------------------------------------------------------------------------------- /public/db/oracle/pic_in.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuozhudd/Meteorological-data-processing-project/HEAD/public/db/oracle/pic_in.jpeg -------------------------------------------------------------------------------- /public/db/oracle/pic_out.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuozhudd/Meteorological-data-processing-project/HEAD/public/db/oracle/pic_out.jpeg -------------------------------------------------------------------------------- /idc/sql/T_USERANDINTER.sql: -------------------------------------------------------------------------------- 1 | delete from T_USERANDINTER; 2 | insert into T_USERANDINTER select T_USERINFO.username,T_INTERCFG.intername from T_USERINFO,T_INTERCFG where T_USERINFO.rsts=1 and T_INTERCFG.rsts=1; 3 | 4 | exit; 5 | -------------------------------------------------------------------------------- /idc/sql/T_USERINFO.sql: -------------------------------------------------------------------------------- 1 | delete from T_USERINFO; 2 | 3 | insert into T_USERINFO(username,passwd,appname,keyid) values('ty','typwd','台风网',SEQ_USERINFO.nextval); 4 | insert into T_USERINFO(username,passwd,appname,keyid) values('sms','smspwd','短信平台',SEQ_USERINFO.nextval); 5 | 6 | exit; 7 | -------------------------------------------------------------------------------- /idc/sql/cleardata.sql: -------------------------------------------------------------------------------- 1 | #delete from T_ZHOBTMIND where ddatetime 2 | 3 | 4 | 5 | ZHOBTCODE_*.XMLT_ZHOBTCODE11delete from T_ZHOBTCODE1 6 | ZHOBTMIND_*.XMLT_ZHOBTMIND12 7 | 8 | -------------------------------------------------------------------------------- /idc1/ini/xmltodb.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ZHOBTCODE_*.XMLT_ZHOBTCODE11delete from T_ZHOBTCODE1 6 | ZHOBTMIND_*.XMLT_ZHOBTMIND12 7 | 8 | -------------------------------------------------------------------------------- /tools/ini/xmltodb.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ZHOBTCODE_*.XMLT_ZHOBTCODE11delete from T_ZHOBTCODE1 6 | ZHOBTMIND_*.XMLT_ZHOBTMIND11 7 | 8 | -------------------------------------------------------------------------------- /public/demo/demo30.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 程序名:demo30.cpp,此程序演示开发框架中采用MKDIR函数根据绝对路径的文件名或目录名逐级的创建目录。 3 | * 作者:吴从周 4 | */ 5 | #include "../_public.h" 6 | 7 | int main() 8 | { 9 | MKDIR("/tmp/aaa/bbb/ccc/ddd",false); // 创建"/tmp/aaa/bbb/ccc/ddd"目录。 10 | 11 | MKDIR("/tmp/111/222/333/444/data.xml",true); // 创建"/tmp/111/222/333/444"目录。 12 | } 13 | 14 | -------------------------------------------------------------------------------- /public/makefile: -------------------------------------------------------------------------------- 1 | all: lib_public.a lib_public.so libftp.a libftp.so 2 | 3 | lib_public.a:_public.h _public.cpp 4 | g++ -c -o lib_public.a _public.cpp 5 | 6 | lib_public.so:_public.h _public.cpp 7 | g++ -fPIC -shared -o lib_public.so _public.cpp 8 | 9 | libftp.a:ftplib.h ftplib.c 10 | gcc -c -o libftp.a ftplib.c 11 | 12 | libftp.so:ftplib.h ftplib.c 13 | gcc -fPIC -shared -o libftp.so ftplib.c 14 | 15 | clean: 16 | rm -f lib_public.a lib_public.so libftp.a libftp.so 17 | -------------------------------------------------------------------------------- /public/demo/demo7.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 程序名:demo7.cpp,此程序演示开发框架中SPRINTF函数的使用。 3 | * 作者:吴从周 4 | */ 5 | #include "../_public.h" 6 | 7 | int main() 8 | { 9 | char str[21]; // 字符串str的大小是21字节。 10 | 11 | SPRINTF(str,sizeof(str),"name:%s,no:%d","messi",10); 12 | printf("str=%s=\n",str); // 出输结果是str=name:messi,no:10= 13 | 14 | SPRINTF(str,sizeof(str),"name:%s,no:%d,job:%s","messi",10,"striker"); 15 | printf("str=%s=\n",str); // 出输结果是str=name:messi,no:10,job= 16 | } 17 | 18 | -------------------------------------------------------------------------------- /public/demo/demo1.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 程序名:demo1.cpp,此程序演示开发框架中STRCPY函数的使用。 3 | * 作者:吴从周 4 | */ 5 | 6 | 7 | #include "../_public.h" 8 | 9 | int main(int argc,char *argv[]) 10 | { 11 | char str[11]; // 字符串str的大小是11字节。 12 | 13 | STRCPY(str,sizeof(str),"google"); // 待复制的内容没有超过str可以存放字符串的大小。 14 | printf("str=%s=\n",str); // 出输结果是str=google= 15 | 16 | STRCPY(str,sizeof(str),"www.google.com"); // 待复制的内容超过了str可以存放字符串的大小。 17 | printf("str=%s=\n",str); // 出输结果是str=www.google= 18 | } 19 | 20 | -------------------------------------------------------------------------------- /public/demo/demo4.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 程序名:demo4.cpp,此程序演示开发框架中STRCAT函数的使用。 3 | * 作者:吴从周 4 | */ 5 | #include "../_public.h" 6 | 7 | int main() 8 | { 9 | char str[11]; // 字符串str的大小是11字节。 10 | STRCPY(str,sizeof(str),"www"); 11 | 12 | STRCAT(str,sizeof(str),".fr"); // str原有的内容加上待追加的内容没有超过str可以存放的大小。 13 | printf("str=%s=\n",str); // 出输结果是str=www.fr= 14 | 15 | STRCAT(str,sizeof(str),"eecplus.net"); // str原有的内容加上待追加的内容超过了str可以存放的大小。 16 | printf("str=%s=\n",str); // 出输结果是str=www.freecp= 17 | } 18 | 19 | -------------------------------------------------------------------------------- /public/demo/demo29.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 程序名:demo29.cpp,此程序演示开发框架中的CTimer类(计时器)的用法。 3 | * 作者:吴从周 4 | */ 5 | #include "../_public.h" 6 | 7 | int main() 8 | { 9 | CTimer Timer; 10 | 11 | printf("elapsed=%lf\n",Timer.Elapsed()); 12 | sleep(1); 13 | printf("elapsed=%lf\n",Timer.Elapsed()); 14 | sleep(1); 15 | printf("elapsed=%lf\n",Timer.Elapsed()); 16 | usleep(1000); 17 | printf("elapsed=%lf\n",Timer.Elapsed()); 18 | usleep(100); 19 | printf("elapsed=%lf\n",Timer.Elapsed()); 20 | sleep(10); 21 | printf("elapsed=%lf\n",Timer.Elapsed()); 22 | } 23 | 24 | -------------------------------------------------------------------------------- /public/demo/demo28.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 程序名:demo28.cpp,此程序演示开发框架中采用AddTime进行时间的运算。 3 | * 作者:吴从周 4 | */ 5 | #include "../_public.h" 6 | 7 | int main() 8 | { 9 | time_t ltime; 10 | char strtime[20]; 11 | 12 | memset(strtime,0,sizeof(strtime)); 13 | strcpy(strtime,"2020-01-01 12:35:22"); 14 | 15 | AddTime(strtime,strtime,0-1*24*60*60); // 减一天。 16 | printf("strtime=%s\n",strtime); // 输出strtime=2019-12-31 12:35:22 17 | 18 | AddTime(strtime,strtime,2*24*60*60); // 加两天。 19 | printf("strtime=%s\n",strtime); // 输出strtime=2020-01-02 12:35:22 20 | } 21 | 22 | -------------------------------------------------------------------------------- /myIdc/c/makefile: -------------------------------------------------------------------------------- 1 | # 开发框架头文件路径 2 | PUBINCL = -I/szz/project/public 3 | 4 | # 开发框架cpp文件名,直接包含进来,没有使用链接库,是为了方便调试 5 | PUBCPP = /szz/project/public/_public.cpp 6 | 7 | # 编译参数 8 | CFLAGS = -g 9 | 10 | all:crtsurfdata1 crtsurfdata2 11 | 12 | crtsurfdata1:crtsurfdata1.cpp 13 | g++ $(CFLAGS) -o crtsurfdata1 crtsurfdata1.cpp $(PUBINCL) $(PUBCPP) -lm -lc 14 | cp crtsurfdata1 ../bin/. 15 | 16 | crtsurfdata2:crtsurfdata2.cpp 17 | g++ $(CFLAGS) -o crtsurfdata2 crtsurfdata2.cpp $(PUBINCL) $(PUBCPP) -lm -lc 18 | cp crtsurfdata2 ../bin/. 19 | clean: 20 | rm crtsurfdata1 crtsurfdata2 21 | 22 | -------------------------------------------------------------------------------- /public/demo/demo32.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 程序名:demo32.cpp,此程序演示开发框架中采用CDir类获取某目录及其子目录中的文件列表信息。 3 | * 作者:吴从周 4 | */ 5 | #include "../_public.h" 6 | 7 | int main(int argc,char *argv[]) 8 | { 9 | if (argc != 2) { printf("请指定目录名。\n"); return -1; } 10 | 11 | CDir Dir; 12 | 13 | if (Dir.OpenDir(argv[1],"*.h,*cpp",100,true,true)==false) 14 | { 15 | printf("Dir.OpenDir(%s) failed.\n",argv[1]); return -1; 16 | } 17 | 18 | while(Dir.ReadDir()==true) 19 | { 20 | printf("filename=%s,mtime=%s,size=%d\n",Dir.m_FullFileName,Dir.m_ModifyTime,Dir.m_FileSize); 21 | } 22 | } 23 | 24 | -------------------------------------------------------------------------------- /public/demo/demo8.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 程序名:demo8.cpp,此程序演示开发框架中SNPRINTF函数的使用。 3 | * 作者:吴从周 4 | */ 5 | #include "../_public.h" 6 | 7 | int main() 8 | { 9 | char str[26]; // 字符串str的大小是11字节。 10 | 11 | SNPRINTF(str,sizeof(str),5,"messi"); 12 | printf("str=%s=\n",str); // 出输结果是str=mess= 13 | 14 | SNPRINTF(str,sizeof(str),9,"name:%s,no:%d,job:%s","messi",10,"striker"); 15 | printf("str=%s=\n",str); // 出输结果是str=name:mes= 16 | 17 | SNPRINTF(str,sizeof(str),30,"name:%s,no:%d,job:%s","messi",10,"striker"); 18 | printf("str=%s=\n",str); // 出输结果是str=name:messi,no:10,job:stri= 19 | } 20 | 21 | -------------------------------------------------------------------------------- /public/demo/demo24.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 程序名:demo24.cpp,此程序演示开发框架中LocalTime时间函数的使用。 3 | * 作者:吴从周 4 | */ 5 | #include "../_public.h" 6 | 7 | int main() 8 | { 9 | char strtime[20]; 10 | memset(strtime,0,sizeof(strtime)); 11 | 12 | LocalTime(strtime,"yyyy-mm-dd hh24:mi:ss",-30); // 获取30秒前的时间。 13 | printf("strtime1=%s\n",strtime); 14 | 15 | LocalTime(strtime,"yyyy-mm-dd hh24:mi:ss"); // 获取当前时间。 16 | printf("strtime2=%s\n",strtime); 17 | 18 | LocalTime(strtime,"yyyy-mm-dd hh24:mi:ss",30); // 获取30秒后的时间。 19 | printf("strtime3=%s\n",strtime); 20 | 21 | printf("=%d\n",time(0)); 22 | } 23 | 24 | -------------------------------------------------------------------------------- /public/demo/demo26.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 程序名:demo26.cpp,此程序演示开发框架中整数表示的时间和字符串表示的时间之间的转换。 3 | * 作者:吴从周 4 | */ 5 | #include "../_public.h" 6 | 7 | int main() 8 | { 9 | time_t ltime; 10 | char strtime[20]; 11 | 12 | memset(strtime,0,sizeof(strtime)); 13 | strcpy(strtime,"2020-01-01 12:35:22"); 14 | 15 | ltime=strtotime(strtime); // 转换为整数的时间 16 | printf("ltime=%ld\n",ltime); // 输出ltime=1577853322 17 | 18 | memset(strtime,0,sizeof(strtime)); 19 | timetostr(ltime,strtime,"yyyy-mm-dd hh24:mi:ss"); // 转换为字符串的时间 20 | printf("strtime=%s\n",strtime); // 输出strtime=2020-01-01 12:35:22 21 | } 22 | 23 | -------------------------------------------------------------------------------- /public/demo/demo2.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 程序名:demo2.cpp,此程序演示开发框架中STRNCPY函数的使用。 3 | * 作者:吴从周 4 | */ 5 | #include "../_public.h" 6 | 7 | int main() 8 | { 9 | char str[11]; // 字符串str的大小是11字节。 10 | 11 | STRNCPY(str,sizeof(str),"google",5); // 待复制的内容没有超过str可以存放字符串的大小。 12 | printf("str=%s=\n",str); // 出输结果是str=googl= 13 | 14 | STRNCPY(str,sizeof(str),"www.google.com",8); // 待复制的内容没有超过str可以存放字符串的大小。 15 | printf("str=%s=\n",str); // 出输结果是str=www.goog= 16 | 17 | STRNCPY(str,sizeof(str),"www.google.com",17); // 待复制的内容超过了str可以存放字符串的大小。 18 | printf("str=%s=\n",str); // 出输结果是str=www.google= 19 | } 20 | 21 | -------------------------------------------------------------------------------- /public/demo/demo18.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 程序名:demo18.cpp,此程序演示开发框架正则表达示MatchStr函数的使用。 3 | * 作者:吴从周 4 | */ 5 | #include "../_public.h" 6 | 7 | int main() 8 | { 9 | char filename[301]; 10 | STRCPY(filename,sizeof(filename),"_public.h"); 11 | 12 | // 以下代码将输出yes。 13 | if (MatchStr(filename,"*.h,*.cpp")==true) printf("yes\n"); 14 | else printf("no\n"); 15 | 16 | // 以下代码将输出yes。 17 | if (MatchStr(filename,"*.H")==true) printf("yes\n"); 18 | else printf("no\n"); 19 | 20 | // 以下代码将输出no。 21 | if (MatchStr(filename,"*.cpp")==true) printf("yes\n"); 22 | else printf("no\n"); 23 | 24 | return 0; 25 | } 26 | 27 | -------------------------------------------------------------------------------- /public/demo/demo16.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 程序名:demo16.cpp,此程序演示开发框架中PickNumber函数的使用。 3 | * 作者:吴从周 4 | */ 5 | #include "../_public.h" 6 | 7 | int main() 8 | { 9 | char str[26]; // 字符串str的大小是11字节。 10 | 11 | STRCPY(str,sizeof(str),"iab+12.3xy"); 12 | PickNumber(str,str,false,false); 13 | printf("str=%s=\n",str); // 出输结果是str=123= 14 | 15 | STRCPY(str,sizeof(str),"iab+12.3xy"); 16 | PickNumber(str,str,true,false); 17 | printf("str=%s=\n",str); // 出输结果是str=+123= 18 | 19 | STRCPY(str,sizeof(str),"iab+12.3xy"); 20 | PickNumber(str,str,true,true); 21 | printf("str=%s=\n",str); // 出输结果是str=+12.3= 22 | } 23 | 24 | -------------------------------------------------------------------------------- /public/demo/demo10.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 程序名:demo10.cpp,此程序演示开发框架中删除字符串左、右、两边指定字符的使用。 3 | * 作者:吴从周 4 | */ 5 | #include "../_public.h" 6 | 7 | int main() 8 | { 9 | char str[11]; // 字符串str的大小是11字节。 10 | 11 | STRCPY(str,sizeof(str)," 西施 "); 12 | DeleteLChar(str,' '); // 删除str左边的空格 13 | printf("str=%s=\n",str); // 出输结果是str=西施 = 14 | 15 | STRCPY(str,sizeof(str)," 西施 "); 16 | DeleteRChar(str,' '); // 删除str右边的空格 17 | printf("str=%s=\n",str); // 出输结果是str= 西施= 18 | 19 | STRCPY(str,sizeof(str)," 西施 "); 20 | DeleteLRChar(str,' '); // 删除str两边的空格 21 | printf("str=%s=\n",str); // 出输结果是str=西施= 22 | } 23 | 24 | -------------------------------------------------------------------------------- /public/demo/demo43.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 程序名:demo43.cpp,此程序演示开发框架的CLogFile类的日志文件的切换。 3 | * 作者:吴从周 4 | */ 5 | #include "../_public.h" 6 | 7 | int main() 8 | { 9 | CLogFile logfile; 10 | 11 | // 打开日志文件,如果"/tmp/log"不存在,就创建它,但是要确保当前用户具备创建目录的权限。 12 | if (logfile.Open("/tmp/log/demo43.log")==false) 13 | { printf("logfile.Open(/tmp/log/demo43.log) failed.\n"); return -1; } 14 | 15 | logfile.Write("demo43程序开始运行。\n"); 16 | 17 | // 让程序循环10000000,生成足够大的日志。 18 | for (int ii=0;ii<10000000;ii++) 19 | { 20 | logfile.Write("本程序演示日志文件的切换,这是第%010d条记录。\n",ii); 21 | } 22 | 23 | logfile.Write("demo43程序运行结束。\n"); 24 | } 25 | 26 | -------------------------------------------------------------------------------- /public/demo/demo37.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 程序名:demo37.cpp,此程序演示开发框架中FGETS函数的用法。 3 | * 作者:吴从周 4 | */ 5 | #include "../_public.h" 6 | 7 | int main() 8 | { 9 | FILE *fp=0; 10 | 11 | if ( (fp=FOPEN("/tmp/aaa/bbb/ccc/tmp.xml","r"))==0) 12 | { 13 | printf("FOPEN(/tmp/aaa/bbb/ccc/tmp.xml) %d:%s\n",errno,strerror(errno)); return -1; 14 | } 15 | 16 | char strBuffer[301]; 17 | 18 | while (true) 19 | { 20 | memset(strBuffer,0,sizeof(strBuffer)); 21 | //if (fgets(strBuffer,300,fp)==false) break; // 行内容以"\n"结束。 22 | if (FGETS(fp,strBuffer,300,"")==false) break; // 行内容以""结束。 23 | 24 | printf("strBuffer=%s",strBuffer); 25 | } 26 | 27 | fclose(fp); 28 | } 29 | 30 | -------------------------------------------------------------------------------- /public/db/oracle/tmp.sh: -------------------------------------------------------------------------------- 1 | iconv -f gbk -t utf-8 ../oracle1/blobtofile.cpp >blobtofile.cpp 2 | iconv -f gbk -t utf-8 ../oracle1/clobtofile.cpp >clobtofile.cpp 3 | iconv -f gbk -t utf-8 ../oracle1/counttable.cpp >counttable.cpp 4 | iconv -f gbk -t utf-8 ../oracle1/createtable.cpp >createtable.cpp 5 | iconv -f gbk -t utf-8 ../oracle1/deletetable.cpp >deletetable.cpp 6 | iconv -f gbk -t utf-8 ../oracle1/execplsql.cpp >execplsql.cpp 7 | iconv -f gbk -t utf-8 ../oracle1/filetoblob.cpp >filetoblob.cpp 8 | iconv -f gbk -t utf-8 ../oracle1/filetoclob.cpp >filetoclob.cpp 9 | iconv -f gbk -t utf-8 ../oracle1/inserttable.cpp >inserttable.cpp 10 | iconv -f gbk -t utf-8 ../oracle1/selecttable.cpp >selecttable.cpp 11 | iconv -f gbk -t utf-8 ../oracle1/updatetable.cpp >updatetable.cpp 12 | -------------------------------------------------------------------------------- /public/demo/demo36.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 程序名:demo36.cpp,此程序演示开发框架中FOPEN函数的用法。 3 | * 作者:吴从周 4 | */ 5 | #include "../_public.h" 6 | 7 | int main() 8 | { 9 | FILE *fp=0; 10 | 11 | // 用FOPEN函数代替fopen库函数,如果目录/tmp/aaa/bbb/ccc不存在,会创建它。 12 | if ( (fp=FOPEN("/tmp/aaa/bbb/ccc/tmp.xml","w"))==0) 13 | { 14 | printf("FOPEN(/tmp/aaa/bbb/ccc/tmp.xml) %d:%s\n",errno,strerror(errno)); return -1; 15 | } 16 | 17 | // 向文件中写入两行超女数据。 18 | fprintf(fp,"\n"\ 19 | "妲已28火辣漂亮商要亡,关我什么事。\n"\ 20 | "西施25火辣漂亮1、中国排名第一的美女;\n"\ 21 | "2、男朋友是范蠡;\n"\ 22 | "3、老公是夫差,被勾践弄死了。\n"\ 23 | "\n"); 24 | 25 | fclose(fp); // 关闭文件。 26 | } 27 | 28 | -------------------------------------------------------------------------------- /public/demo/demo5.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 程序名:demo5.cpp,此程序演示开发框架中STRNCAT函数的使用。 3 | * 作者:吴从周 4 | */ 5 | #include "../_public.h" 6 | 7 | int main() 8 | { 9 | char str[11]; // 字符串str的大小是11字节。 10 | 11 | STRCPY(str,sizeof(str),"www"); 12 | STRNCAT(str,sizeof(str),".free",10); // str原有的内容加上待追加的内容没有超过str可以存放的大小。 13 | printf("str=%s=\n",str); // 出输结果是str=www.free= 14 | 15 | STRCPY(str,sizeof(str),"www"); 16 | STRNCAT(str,sizeof(str),".freecplus.com",6); // str原有的内容加上待追加的内容没有超过str可以存放的大小。 17 | printf("str=%s=\n",str); // 出输结果是str=www.freec= 18 | 19 | STRCPY(str,sizeof(str),"www"); 20 | STRNCAT(str,sizeof(str),".freecplus.com",10); // str原有的内容加上待追加的内容超过了str可以存放的大小。 21 | printf("str=%s=\n",str); // 出输结果是str=www.freecp= 22 | } 23 | 24 | -------------------------------------------------------------------------------- /pthread/book10.cpp: -------------------------------------------------------------------------------- 1 | // 本程序演示线程和信号。 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | void func(int sig) 10 | { 11 | printf("func catch signal %d\n",sig); 12 | } 13 | 14 | void *thmain(void *arg); // 线程主函数。 15 | 16 | int main(int argc,char *argv[]) 17 | { 18 | signal(2,func); 19 | 20 | // 创建线程。 21 | pthread_t thid; 22 | if (pthread_create(&thid,NULL,thmain,NULL)!=0) { printf("pthread_create failed.\n"); exit(-1); } 23 | 24 | sleep(5); pthread_kill(thid,15); sleep(100); 25 | 26 | printf("join ...\n"); 27 | pthread_join(thid,NULL); 28 | printf("join ok.\n"); 29 | } 30 | 31 | void *thmain(void *arg) // 线程主函数。 32 | { 33 | printf("sleep ....\n"); 34 | sleep(10); 35 | printf("sleep ok.\n"); 36 | 37 | return (void *) 1; 38 | } 39 | -------------------------------------------------------------------------------- /public/demo/demo12.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 程序名:demo12.cpp,此程序演示开发框架中字符串大小写转换函数的使用。 3 | * 作者:吴从周 4 | */ 5 | #include "../_public.h" 6 | 7 | int main() 8 | { 9 | char str1[31]; // C语言风格的字符串。 10 | 11 | STRCPY(str1,sizeof(str1),"12abz45ABz8西施。"); 12 | ToUpper(str1); // 把str1中的小写字母转换为大写。 13 | printf("str1=%s=\n",str1); // 出输结果是str1=12ABZ45ABZ8西施。= 14 | 15 | STRCPY(str1,sizeof(str1),"12abz45ABz8西施。"); 16 | ToLower(str1); // 把str1中的大写字母转换为小写。 17 | printf("str1=%s=\n",str1); // 出输结果是str1=12abz45abz8西施。= 18 | 19 | string str2; // C++语言风格的字符串。 20 | 21 | str2="12abz45ABz8西施。"; 22 | ToUpper(str2); // 把str2中的小写字母转换为大写。 23 | printf("str2=%s=\n",str2.c_str()); // 出输结果是str2=12ABZ45ABZ8西施。= 24 | 25 | str2="12abz45ABz8西施。"; 26 | ToLower(str2); // 把str2中的大写字母转换为小写。 27 | printf("str2=%s=\n",str2.c_str()); // 出输结果是str1=12abz45abz8西施。= 28 | } 29 | 30 | -------------------------------------------------------------------------------- /idc/c/killall.sh: -------------------------------------------------------------------------------- 1 | #################################################################### 2 | # 停止数据中心后台服务程序的脚本。 3 | #################################################################### 4 | 5 | killall -9 procctl 6 | killall gzipfiles crtsurfdata deletefiles ftpgetfiles ftpputfiles tcpputfiles tcpgetfiles fileserver 7 | killall obtcodetodb obtmindtodb execsql dminingmysql xmltodb syncupdate syncincrement 8 | killall deletetable migratetable xmltodb_oracle migratetable_oracle deletetable_oracle 9 | killall syncupdate_oracle syncincrement_oracle 10 | 11 | sleep 3 12 | 13 | killall -9 gzipfiles crtsurfdata deletefiles ftpgetfiles ftpputfiles tcpputfiles tcpgetfiles fileserver 14 | killall -9 obtcodetodb obtmindtodb execsql dminingmysql xmltodb syncupdate syncincrement 15 | killall -9 deletetable migratetable xmltodb_oracle migratetable_oracle deletetable_oracle 16 | killall -9 syncupdate_oracle syncincrement_oracle 17 | -------------------------------------------------------------------------------- /pthread/book9.cpp: -------------------------------------------------------------------------------- 1 | // 本程序演示线程的取消。 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | int var=0; 9 | 10 | void *thmain(void *arg); // 线程主函数。 11 | 12 | int main(int argc,char *argv[]) 13 | { 14 | pthread_t thid; 15 | 16 | // 创建线程。 17 | if (pthread_create(&thid,NULL,thmain,NULL)!=0) { printf("pthread_create failed.\n"); exit(-1); } 18 | 19 | usleep(100); pthread_cancel(thid); 20 | 21 | int result=0; 22 | void *ret; 23 | printf("join...\n"); 24 | result=pthread_join(thid,&ret); printf("thid result=%d,ret=%ld\n",result,ret); 25 | printf("join ok.\n"); 26 | 27 | printf("var=%d\n",var); 28 | } 29 | 30 | void *thmain(void *arg) // 线程主函数。 31 | { 32 | // pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,NULL); 33 | 34 | for (var=0;var<400000000;var++) 35 | { 36 | ; 37 | pthread_testcancel(); 38 | } 39 | return (void *) 1; 40 | } 41 | -------------------------------------------------------------------------------- /idc/c/rc.local: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # THIS FILE IS ADDED FOR COMPATIBILITY PURPOSES 3 | # 4 | # It is highly advisable to create own systemd services or udev rules 5 | # to run scripts during boot instead of using this file. 6 | # 7 | # In contrast to previous versions due to parallel execution during boot 8 | # this script will NOT be run after all other services. 9 | # 10 | # Please note that you must run 'chmod +x /etc/rc.d/rc.local' to ensure 11 | # that this script will be executed during boot. 12 | 13 | touch /var/lock/subsys/local 14 | 15 | # 启动守护程序,检查服务程序是否超时。 16 | /project/tools1/bin/procctl 30 /project/tools1/bin/checkproc /tmp/log/checkproc.log 17 | 18 | # 启动数据中心的后台服务程序。 19 | #su - wucz -c "/bin/sh /project/idc1/c/start.sh" 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | # 启动mysql数据库。 31 | #/usr/local/mysql/support-files/mysql.server start 32 | 33 | # 启动网络代理程序。 34 | #/project/tools/bin/procctl 10 /project/tools/bin/rinetd 35 | 36 | -------------------------------------------------------------------------------- /pthread/book4.cpp: -------------------------------------------------------------------------------- 1 | // 本程序演示线程参数的传递(用结构体的地址传递多个参数)。 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | void *thmain(void *arg); // 线程的主函数。 9 | 10 | struct st_args 11 | { 12 | int no; // 线程编号。 13 | char name[51]; // 线程名。 14 | }; 15 | 16 | int main(int argc,char *argv[]) 17 | { 18 | pthread_t thid=0; 19 | 20 | // 创建线程。 21 | struct st_args *stargs=new struct st_args; 22 | stargs->no=15; strcpy(stargs->name,"测试线程"); 23 | if (pthread_create(&thid,NULL,thmain,stargs)!=0) { printf("pthread_create failed.\n"); exit(-1); } 24 | 25 | // 等待子线程退出。 26 | printf("join...\n"); 27 | pthread_join(thid,NULL); 28 | printf("join ok.\n"); 29 | } 30 | 31 | void *thmain(void *arg) // 线程主函数。 32 | { 33 | struct st_args *pst=(struct st_args *)arg; 34 | printf("no=%d,name=%s\n",pst->no,pst->name); 35 | delete pst; 36 | printf("线程开始运行。\n"); 37 | } 38 | 39 | -------------------------------------------------------------------------------- /public/demo/demo51.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 程序名:demo51.cpp,此程序演示采用开发框架的Cftp类上传文件。 3 | * 作者:吴从周 4 | */ 5 | #include "../_ftp.h" 6 | 7 | int main(int argc,char *argv[]) 8 | { 9 | Cftp ftp; 10 | 11 | // 登录远程FTP服务器,请改为你自己服务器的ip地址。 12 | if (ftp.login("172.16.0.15:21","wucz","freecpluspwd",FTPLIB_PASSIVE) == false) 13 | { 14 | printf("ftp.login(172.16.0.15:21(wucz/freecpluspwd)) failed.\n"); return -1; 15 | } 16 | 17 | // 在ftp服务器上创建/home/wucz/tmp,注意,如果目录已存在,会返回失败。 18 | if (ftp.mkdir("/home/wucz/tmp")==false) { printf("ftp.mkdir() failed.\n"); return -1; } 19 | 20 | // 把ftp服务器上的工作目录切换到/home/wucz/tmp 21 | if (ftp.chdir("/home/wucz/tmp")==false) { printf("ftp.chdir() failed.\n"); return -1; } 22 | 23 | // 把本地的demo51.cpp上传到ftp服务器的当前工作目录。 24 | ftp.put("demo51.cpp","demo51.cpp"); 25 | 26 | // 如果不调用chdir切换工作目录,以下代码也可以直接上传文件。 27 | // ftp.put("demo51.cpp","/home/wucz/tmp/demo51.cpp"); 28 | 29 | printf("put demo51.cpp ok.\n"); 30 | } 31 | 32 | -------------------------------------------------------------------------------- /idc/c/crtsurfdata1.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 程序名:crtsurfdata1.cpp 本程序用于生成全国气象站点观测的分钟数据。 3 | * 作者:吴从周。 4 | */ 5 | 6 | #include "_public.h" 7 | 8 | CLogFile logfile; // 日志类。 9 | 10 | int main(int argc,char *argv[]) 11 | { 12 | if (argc!=4) 13 | { 14 | // 如果参数非法,给出帮助文档。 15 | printf("Using:./crtsurfdata1 inifile outpath logfile\n"); 16 | printf("Example:/project/idc1/bin/crtsurfdata1 /project/idc1/ini/stcode.ini /tmp/surfdata /log/idc/crtsurfdata1.log\n\n"); 17 | 18 | printf("inifile 全国气象站点参数文件名。\n"); 19 | printf("outpath 全国气象站点数据文件存放的目录。\n"); 20 | printf("logfile 本程序运行的日志文件名。\n\n"); 21 | 22 | return -1; 23 | } 24 | 25 | // 打开程序的日志文件。 26 | if (logfile.Open(argv[3],"a+",false)==false) 27 | { 28 | printf("logfile.Open(%s) failed.\n",argv[3]); return -1; 29 | } 30 | 31 | logfile.Write("crtsurfdata1 开始运行。\n"); 32 | 33 | // 在这里插入处理业务的代码。 34 | 35 | logfile.WriteEx("crtsurfdata1 运行结束。\n"); 36 | 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /public/demo/demo47.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 程序名:demo47.cpp,此程序演示采用开发框架的CTcpClient类实现socket通信的客户端。 3 | * 作者:吴从周 4 | */ 5 | #include "../_public.h" 6 | 7 | int main(int argc,char *argv[]) 8 | { 9 | CTcpClient TcpClient; // 创建客户端的对象。 10 | 11 | if (TcpClient.ConnectToServer("172.17.0.15",5858)==false) // 向服务端发起连接请求。 12 | { 13 | printf("TcpClient.ConnectToServer(\"172.17.0.15\",5858) failed.\n"); return -1; 14 | } 15 | 16 | char strbuffer[1024]; // 存放数据的缓冲区。 17 | 18 | for (int ii=0;ii<5;ii++) // 利用循环,与服务端进行5次交互。 19 | { 20 | memset(strbuffer,0,sizeof(strbuffer)); 21 | snprintf(strbuffer,50,"这是第%d个超级女生,编号%03d。",ii+1,ii+1); 22 | printf("发送:%s\n",strbuffer); 23 | if (TcpClient.Write(strbuffer)==false) break; // 向服务端发送请求报文。 24 | 25 | memset(strbuffer,0,sizeof(strbuffer)); 26 | if (TcpClient.Read(strbuffer,20)==false) break; // 接收服务端的回应报文。 27 | printf("接收:%s\n",strbuffer); 28 | 29 | sleep(1); 30 | } 31 | 32 | // 程序直接退出,析构函数会释放资源。 33 | } 34 | -------------------------------------------------------------------------------- /pthread/book11.cpp: -------------------------------------------------------------------------------- 1 | // 本程序演示线程安全。 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | std::atomic var; 11 | 12 | void *thmain(void *arg); // 线程主函数。 13 | 14 | int main(int argc,char *argv[]) 15 | { 16 | pthread_t thid1,thid2; 17 | 18 | // 创建线程。 19 | if (pthread_create(&thid1,NULL,thmain,NULL)!=0) { printf("pthread_create failed.\n"); exit(-1); } 20 | if (pthread_create(&thid2,NULL,thmain,NULL)!=0) { printf("pthread_create failed.\n"); exit(-1); } 21 | 22 | // 等待子线程退出。 23 | printf("join...\n"); 24 | pthread_join(thid1,NULL); 25 | pthread_join(thid2,NULL); 26 | printf("join ok.\n"); 27 | 28 | // printf("var=%d\n",var); 29 | std::cout << "var=" << var << std::endl; 30 | } 31 | 32 | void *thmain(void *arg) // 线程主函数。 33 | { 34 | for (int ii=0;ii<1000000;ii++) 35 | { 36 | var++; 37 | // __sync_fetch_and_add(&var,1); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /public/socket/demo07.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 程序名:demo07.cpp,此程序用于演示采用TcpClient类实现socket通讯的客户端。 3 | * 作者:吴从周。 4 | */ 5 | #include "../_public.h" 6 | 7 | int main(int argc,char *argv[]) 8 | { 9 | if (argc!=3) 10 | { 11 | printf("Using:./demo07 ip port\nExample:./demo07 127.0.0.1 5005\n\n"); return -1; 12 | } 13 | 14 | CTcpClient TcpClient; 15 | 16 | // 向服务端发起连接请求。 17 | if (TcpClient.ConnectToServer(argv[1],atoi(argv[2]))==false) 18 | { 19 | printf("TcpClient.ConnectToServer(%s,%s) failed.\n",argv[1],argv[2]); return -1; 20 | } 21 | 22 | char buffer[102400]; 23 | 24 | // 与服务端通讯,发送一个报文后等待回复,然后再发下一个报文。 25 | for (int ii=0;ii<100000;ii++) 26 | { 27 | SPRINTF(buffer,sizeof(buffer),"这是第%d个超级女生,编号%03d。",ii+1,ii+1); 28 | if (TcpClient.Write(buffer)==false) break; // 向服务端发送请求报文。 29 | printf("发送:%s\n",buffer); 30 | 31 | memset(buffer,0,sizeof(buffer)); 32 | if (TcpClient.Read(buffer)==false) break; // 接收服务端的回应报文。 33 | printf("接收:%s\n",buffer); 34 | 35 | sleep(1); // 每隔一秒后再次发送报文。 36 | } 37 | } 38 | 39 | -------------------------------------------------------------------------------- /myIdc/c/crtsurfdata1.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * description: crtsurfdata1.cpp 本程序用于生成全国气象站点观测的分钟数据 3 | * author: songzhuozhu 4 | */ 5 | 6 | 7 | #include "_public.h" 8 | 9 | CLogFile logfile(10); // 日志类一般定义为全局变量 10 | 11 | 12 | int main(int argc, char*argv[]) 13 | { 14 | // inifile outpath logfile 15 | if (argc != 4) 16 | { 17 | printf("Using:./crtsurfdata1 inifile outpath logfile\n"); 18 | printf("Example:/szz/project/myIdc/bin/crtsurfdata1 /szz/project/myIdc/ini/stcode.ini /tmp/surfdata /log/idc/crtsurfdata.log\n\n"); 19 | 20 | printf("inifle 全国气象站点参数文件名。\n"); 21 | printf("outpath 全国气象站点数据文件存放的目录。\n"); 22 | printf("logfile 本程序运行的日志文件名。\n"); 23 | 24 | return -1; 25 | } 26 | 27 | if (logfile.Open(argv[3],"a+",false) == false) 28 | { 29 | printf("logfile.Open(%s) failed.\n",argv[3]); 30 | return -1; 31 | } 32 | 33 | logfile.Write("crtsurfdata1 开始运行。\n"); 34 | 35 | // 写入业务逻辑代码 36 | 37 | logfile.Write("crtsurfdata1 运行结束。\n"); 38 | logfile.WriteEx("crtsurfdata1 运行结束。"); 39 | 40 | 41 | 42 | return 0; 43 | } -------------------------------------------------------------------------------- /public/demo/demo48.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 程序名:demo48.cpp,此程序演示采用开发框架的CTcpServer类实现socket通信的服务端。 3 | * 作者:吴从周 4 | */ 5 | #include "../_public.h" 6 | 7 | int main(int argc,char *argv[]) 8 | { 9 | CTcpServer TcpServer; // 创建服务端对象。 10 | 11 | if (TcpServer.InitServer(5858)==false) // 初始化TcpServer的通信端口。 12 | { 13 | printf("TcpServer.InitServer(5858) failed.\n"); return -1; 14 | } 15 | 16 | if (TcpServer.Accept()==false) // 等待客户端连接。 17 | { 18 | printf("TcpServer.Accept() failed.\n"); return -1; 19 | } 20 | 21 | printf("客户端(%s)已连接。\n",TcpServer.GetIP()); 22 | 23 | char strbuffer[1024]; // 存放数据的缓冲区。 24 | 25 | while (true) 26 | { 27 | memset(strbuffer,0,sizeof(strbuffer)); 28 | if (TcpServer.Read(strbuffer,300)==false) break; // 接收客户端发过来的请求报文。 29 | printf("接收:%s\n",strbuffer); 30 | 31 | strcat(strbuffer,"ok"); // 在客户端的报文后加上"ok"。 32 | printf("发送:%s\n",strbuffer); 33 | if (TcpServer.Write(strbuffer)==false) break; // 向客户端回应报文。 34 | } 35 | 36 | printf("客户端已断开。\n"); // 程序直接退出,析构函数会释放资源。 37 | } 38 | -------------------------------------------------------------------------------- /pthread/book16.cpp: -------------------------------------------------------------------------------- 1 | // 本程序演示线程同步-信号量。 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | int var; 10 | 11 | sem_t sem; // 声明信号量。 12 | 13 | void *thmain(void *arg); // 线程主函数。 14 | 15 | int main(int argc,char *argv[]) 16 | { 17 | sem_init(&sem,0,1); // 初始化信号量。 18 | 19 | pthread_t thid1,thid2; 20 | 21 | // 创建线程。 22 | if (pthread_create(&thid1,NULL,thmain,NULL)!=0) { printf("pthread_create failed.\n"); exit(-1); } 23 | if (pthread_create(&thid2,NULL,thmain,NULL)!=0) { printf("pthread_create failed.\n"); exit(-1); } 24 | 25 | // 等待子线程退出。 26 | printf("join...\n"); 27 | pthread_join(thid1,NULL); 28 | pthread_join(thid2,NULL); 29 | printf("join ok.\n"); 30 | 31 | printf("var=%d\n",var); 32 | 33 | sem_destroy(&sem); // 销毁信号量。 34 | } 35 | 36 | void *thmain(void *arg) // 线程主函数。 37 | { 38 | for (int ii=0;ii<1000000;ii++) 39 | { 40 | sem_wait(&sem); // 加锁。 41 | var++; 42 | sem_post(&sem); // 解锁。 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /public/socket/demo27.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 程序名:demo27.cpp,此程序用于演示HTTP客户端。 3 | * 作者:吴从周。 4 | */ 5 | #include "../_public.h" 6 | 7 | int main(int argc,char *argv[]) 8 | { 9 | if (argc!=3) 10 | { 11 | printf("Using:./demo27 ip port\nExample:./demo27 www.weather.com.cn 80\n\n"); return -1; 12 | } 13 | 14 | CTcpClient TcpClient; 15 | 16 | // 向服务端发起连接请求。 17 | if (TcpClient.ConnectToServer(argv[1],atoi(argv[2]))==false) 18 | { 19 | printf("TcpClient.ConnectToServer(%s,%s) failed.\n",argv[1],argv[2]); return -1; 20 | } 21 | 22 | char buffer[102400]; 23 | memset(buffer,0,sizeof(buffer)); 24 | 25 | // 生成http请求报文。 26 | sprintf(buffer,\ 27 | "GET / HTTP/1.1\r\n"\ 28 | "Host: %s:%s\r\n"\ 29 | "\r\n",argv[1],argv[2]); 30 | 31 | // 用原生的send函数把http报文发送给服务端。 32 | send(TcpClient.m_connfd,buffer,strlen(buffer),0); 33 | 34 | // 接收服务端返回的网页内容。 35 | while (true) 36 | { 37 | memset(buffer,0,sizeof(buffer)); 38 | if (recv(TcpClient.m_connfd,buffer,102400,0)<=0) return 0; 39 | printf("%s",buffer); 40 | } 41 | } 42 | 43 | -------------------------------------------------------------------------------- /public/socket/demo08.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 程序名:demo08.cpp,此程序用于演示采用TcpServer类实现socket通讯的服务端。 3 | * 作者:吴从周 4 | */ 5 | #include "../_public.h" 6 | 7 | int main(int argc,char *argv[]) 8 | { 9 | if (argc!=2) 10 | { 11 | printf("Using:./demo08 port\nExample:./demo08 5005\n\n"); return -1; 12 | } 13 | 14 | CTcpServer TcpServer; 15 | 16 | // 服务端初始化。 17 | if (TcpServer.InitServer(atoi(argv[1]))==false) 18 | { 19 | printf("TcpServer.InitServer(%s) failed.\n",argv[1]); return -1; 20 | } 21 | 22 | // 等待客户端的连接请求。 23 | if (TcpServer.Accept()==false) 24 | { 25 | printf("TcpServer.Accept() failed.\n"); return -1; 26 | } 27 | 28 | printf("客户端(%s)已连接。\n",TcpServer.GetIP()); 29 | 30 | char buffer[102400]; 31 | 32 | // 与客户端通讯,接收客户端发过来的报文后,回复ok。 33 | while (1) 34 | { 35 | memset(buffer,0,sizeof(buffer)); 36 | if (TcpServer.Read(buffer)==false) break; // 接收客户端的请求报文。 37 | printf("接收:%s\n",buffer); 38 | 39 | strcpy(buffer,"ok"); 40 | if (TcpServer.Write(buffer)==false) break; // 向客户端发送响应结果。 41 | printf("发送:%s\n",buffer); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /pthread/book5.cpp: -------------------------------------------------------------------------------- 1 | // 本程序演示线程线程退出(终止)的状态。 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | void *thmain(void *arg); // 线程的主函数。 9 | 10 | struct st_ret 11 | { 12 | int retcode; // 返回代码。 13 | char message[1024]; // 返回内容。 14 | }; 15 | 16 | int main(int argc,char *argv[]) 17 | { 18 | pthread_t thid=0; 19 | 20 | // 创建线程。 21 | if (pthread_create(&thid,NULL,thmain,NULL)!=0) { printf("pthread_create failed.\n"); exit(-1); } 22 | 23 | // 等待子线程退出。 24 | printf("join...\n"); 25 | struct st_ret *pst=0; 26 | pthread_join(thid,(void **)&pst); 27 | printf("retcode=%d,message=%s\n",pst->retcode,pst->message); 28 | delete pst; 29 | printf("join ok.\n"); 30 | } 31 | 32 | void *thmain(void *arg) // 线程主函数。 33 | { 34 | printf("线程开始运行。\n"); 35 | 36 | // 注意,如果用结构体的地址作为线程的返回值,必须保存在线程主函数结束后地址仍是有效的。 37 | // 所以,要采用动态分配内存的方法,不能用局部变量。 38 | struct st_ret *ret=new struct st_ret; 39 | ret->retcode=1121; 40 | strcpy(ret->message,"测试内容。"); 41 | pthread_exit((void *)ret); 42 | } 43 | 44 | -------------------------------------------------------------------------------- /public/db/oracle/deletetable.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 程序名:deletetable.cpp,此程序演示开发框架操作Oracle数据库(删除表中的记录)。 3 | * 作者:吴从周。 4 | */ 5 | #include "_ooci.h" // 开发框架操作Oracle的头文件。 6 | 7 | int main(int argc,char *argv[]) 8 | { 9 | connection conn; // 数据库连接类 10 | 11 | // 登录数据库,返回值:0-成功,其它-失败。 12 | // 失败代码在conn.m_cda.rc中,失败描述在conn.m_cda.message中。 13 | if (conn.connecttodb("scott/tiger@snorcl11g_132","Simplified Chinese_China.AL32UTF8")!=0) 14 | { 15 | printf("connect database failed.\n%s\n",conn.m_cda.message); return -1; 16 | } 17 | 18 | sqlstatement stmt(&conn); // 操作SQL语句的对象。 19 | 20 | // 执行SQL语句,一定要判断返回值,0-成功,其它-失败。 21 | // 失败代码在stmt.m_cda.rc中,失败描述在stmt.m_cda.message中。 22 | // 如果不需要绑定输入和输出变量,用stmt.execute()方法直接执行SQL语句,不需要stmt.prepare()。 23 | if (stmt.execute("delete from girls where id>=2 and id<=4") != 0) 24 | { 25 | printf("stmt.execute() failed.\n%s\n%s\n",stmt.m_sql,stmt.m_cda.message); return -1; 26 | } 27 | 28 | // 请注意,stmt.m_cda.rpc变量非常重要,它保存了SQL被执行后影响的记录数。 29 | printf("本次从girls表中删除了%ld条记录。\n",stmt.m_cda.rpc); 30 | 31 | // 提交事务 32 | conn.commit(); 33 | } 34 | 35 | -------------------------------------------------------------------------------- /public/demo/demo40.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 程序名:demo40.cpp,此程序演示开发框架中采用CDir类和CFile类处理数据文件的用法。 3 | * 作者:吴从周 4 | */ 5 | #include "../_public.h" 6 | 7 | int main() 8 | { 9 | CDir Dir; 10 | 11 | // 扫描/tmp/data目录下文件名匹配"surfdata_*.xml"的文件。 12 | if (Dir.OpenDir("/tmp/data","surfdata_*.xml")==false) 13 | { 14 | printf("Dir.OpenDir(/tmp/data) failed.\n"); return -1; 15 | } 16 | 17 | CFile File; 18 | 19 | while (Dir.ReadDir()==true) 20 | { 21 | printf("处理文件%s...",Dir.m_FullFileName); 22 | 23 | if (File.Open(Dir.m_FullFileName,"r")==false) 24 | { 25 | printf("failed.File.Open(%s) failed.\n",Dir.m_FullFileName); return -1; 26 | } 27 | 28 | char strBuffer[301]; 29 | 30 | while (true) 31 | { 32 | memset(strBuffer,0,sizeof(strBuffer)); 33 | if (File.FFGETS(strBuffer,300,"")==false) break; // 行内容以""结束。 34 | 35 | // printf("strBuffer=%s",strBuffer); 36 | 37 | // 这里可以插入解析xml字符串并把数据写入数据库的代码。 38 | } 39 | 40 | // 处理完文件中的数据后,关闭文件指针,并删除文件。 41 | File.CloseAndRemove(); 42 | 43 | printf("ok\n"); 44 | } 45 | } 46 | 47 | -------------------------------------------------------------------------------- /public/demo/demo52.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 程序名:demo52.cpp,此程序演示采用开发框架的Cftp类下载文件。 3 | * 作者:吴从周 4 | */ 5 | #include "../_ftp.h" 6 | 7 | int main(int argc,char *argv[]) 8 | { 9 | Cftp ftp; 10 | 11 | // 登录远程FTP服务器,请改为你自己服务器的ip地址。 12 | if (ftp.login("172.16.0.15:21","wucz","freecpluspwd",FTPLIB_PASSIVE) == false) 13 | { 14 | printf("ftp.login(172.16.0.15:21(wucz/freecpluspwd)) failed.\n"); return -1; 15 | } 16 | 17 | // 把服务器上的/home/wucz/tmp/demo51.cpp下载到本地,存为/tmp/test/demo51.cpp。 18 | // 如果本地的/tmp/test目录不存在,就创建它。 19 | if (ftp.get("/home/wucz/tmp/demo51.cpp","/tmp/test/demo51.cpp")==false) 20 | { printf("ftp.get() failed.\n"); return -1; } 21 | 22 | printf("get /home/wucz/tmp/demo51.cpp ok.\n"); 23 | 24 | // 删除服务上的/home/wucz/tmp/demo51.cpp文件。 25 | if (ftp.ftpdelete("/home/wucz/tmp/demo51.cpp")==false) 26 | { printf("ftp.ftpdelete() failed.\n"); return -1; } 27 | 28 | printf("delete /home/wucz/tmp/demo51.cpp ok.\n"); 29 | 30 | // 删除服务器上的/home/wucz/tmp目录,如果目录非空,删除将失败。 31 | if (ftp.rmdir("/home/wucz/tmp")==false) { printf("ftp.rmdir() failed.\n"); return -1; } 32 | } 33 | 34 | -------------------------------------------------------------------------------- /tools/c/_tools.h: -------------------------------------------------------------------------------- 1 | #ifndef _TOOLS_H 2 | #define _TOOLS_H 3 | 4 | #include "_public.h" 5 | #include "_mysql.h" 6 | 7 | // 表的列(字段)信息的结构体。 8 | struct st_columns 9 | { 10 | char colname[31]; // 列名。 11 | char datatype[31]; // 列的数据类型,分为number、date和char三大类。 12 | int collen; // 列的长度,number固定20,date固定19,char的长度由表结构决定。 13 | int pkseq; // 如果列是主键的字段,存放主键字段的顺序,从1开始,不是主键取值0。 14 | }; 15 | 16 | // 获取表全部的列和主键列信息的类。 17 | class CTABCOLS 18 | { 19 | public: 20 | CTABCOLS(); 21 | 22 | int m_allcount; // 全部字段的个数。 23 | int m_pkcount; // 主键字段的个数。 24 | int m_maxcollen; // 全部列中最大的长度,这个成员是后来增加的,课程中并未提及。 25 | 26 | vector m_vallcols; // 存放全部字段信息的容器。 27 | vector m_vpkcols; // 存放主键字段信息的容器。 28 | 29 | char m_allcols[3001]; // 全部的字段名列表,以字符串存放,中间用半角的逗号分隔。 30 | char m_pkcols[301]; // 主键字段名列表,以字符串存放,中间用半角的逗号分隔。 31 | 32 | void initdata(); // 成员变量初始化。 33 | 34 | // 获取指定表的全部字段信息。 35 | bool allcols(connection *conn,char *tablename); 36 | 37 | // 获取指定表的主键字段信息。 38 | bool pkcols(connection *conn,char *tablename); 39 | }; 40 | 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /idc/sql/T_DATATYPE.sql: -------------------------------------------------------------------------------- 1 | insert into T_DATATYPE(typeid,ptypeid,typename,keyid) values('01',null,'国家基本站',SEQ_DATATYPE.nextval); 2 | insert into T_DATATYPE(typeid,ptypeid,typename,keyid) values('02',null,'预报产品' ,SEQ_DATATYPE.nextval); 3 | insert into T_DATATYPE(typeid,ptypeid,typename,keyid) values('03',null,'预警信号' ,SEQ_DATATYPE.nextval); 4 | insert into T_DATATYPE(typeid,ptypeid,typename,keyid) values('04',null,'雷达产品' ,SEQ_DATATYPE.nextval); 5 | 6 | insert into T_DATATYPE(typeid,ptypeid,typename,keyid) values('0101','01','全国站点参数',SEQ_DATATYPE.nextval); 7 | insert into T_DATATYPE(typeid,ptypeid,typename,keyid) values('0102','01','分钟观测数据',SEQ_DATATYPE.nextval); 8 | insert into T_DATATYPE(typeid,ptypeid,typename,keyid) values('0103','01','日统计数据',SEQ_DATATYPE.nextval); 9 | 10 | insert into T_DATATYPE(typeid,ptypeid,typename,keyid) values('0301','03','本市预警信号' ,SEQ_DATATYPE.nextval); 11 | insert into T_DATATYPE(typeid,ptypeid,typename,keyid) values('0302','03','分区预警信号' ,SEQ_DATATYPE.nextval); 12 | insert into T_DATATYPE(typeid,ptypeid,typename,keyid) values('0303','03','全国预警信号' ,SEQ_DATATYPE.nextval); 13 | 14 | exit; 15 | -------------------------------------------------------------------------------- /pthread/book13.cpp: -------------------------------------------------------------------------------- 1 | // 本程序演示线程同步-自旋锁。 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | int var; 9 | 10 | pthread_spinlock_t spin; // 声明自旋锁。 11 | 12 | void *thmain(void *arg); // 线程主函数。 13 | 14 | int main(int argc,char *argv[]) 15 | { 16 | pthread_spin_init(&spin,PTHREAD_PROCESS_PRIVATE); // 初始化自旋锁。 17 | 18 | pthread_t thid1,thid2; 19 | 20 | // 创建线程。 21 | if (pthread_create(&thid1,NULL,thmain,NULL)!=0) { printf("pthread_create failed.\n"); exit(-1); } 22 | if (pthread_create(&thid2,NULL,thmain,NULL)!=0) { printf("pthread_create failed.\n"); exit(-1); } 23 | 24 | // 等待子线程退出。 25 | printf("join...\n"); 26 | pthread_join(thid1,NULL); 27 | pthread_join(thid2,NULL); 28 | printf("join ok.\n"); 29 | 30 | printf("var=%d\n",var); 31 | 32 | pthread_spin_destroy(&spin); // 销毁锁。 33 | } 34 | 35 | void *thmain(void *arg) // 线程主函数。 36 | { 37 | for (int ii=0;ii<1000000;ii++) 38 | { 39 | pthread_spin_lock(&spin); // 加锁。 40 | var++; 41 | pthread_spin_unlock(&spin); // 解锁。 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /public/demo/demo50.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 程序名:demo50.cpp,此程序演示采用开发框架的Cftp类获取服务器文件列表、时间和大小。 3 | * 作者:吴从周 4 | */ 5 | #include "../_ftp.h" 6 | 7 | int main(int argc,char *argv[]) 8 | { 9 | Cftp ftp; 10 | 11 | // 登录远程FTP服务器,请改为你自己服务器的ip地址。 12 | if (ftp.login("172.16.0.15:21","wucz","freecpluspwd",FTPLIB_PASSIVE) == false) 13 | { 14 | printf("ftp.login(172.16.0.15:21(wucz/freecpluspwd)) failed.\n"); return -1; 15 | } 16 | 17 | // 获取服务器上/home/wucz/*.h文件列表,保存在本地的/tmp/list/tmp.list文件中。 18 | // 如果/tmp/list目录不存在,就创建它。 19 | if (ftp.nlist("/home/wucz/*.h","/tmp/list/tmp.list")==false) 20 | { printf("ftp.nlist() failed.\n"); return -1; } 21 | 22 | CFile File; // 采用开发框架的CFile类来操作list文件。 23 | char strFileName[301]; 24 | 25 | File.Open("/tmp/list/tmp.list","r"); // 打开list文件。 26 | 27 | while(true) // 获取每个文件的时间和大小。 28 | { 29 | if (File.Fgets(strFileName,300,true)==false) break; 30 | 31 | ftp.mtime(strFileName); // 获取文件时间。 32 | ftp.size(strFileName); // 获取文件大小。 33 | 34 | printf("filename=%s,mtime=%s,size=%d\n",strFileName,ftp.m_mtime,ftp.m_size); 35 | } 36 | 37 | } 38 | 39 | -------------------------------------------------------------------------------- /pthread/book7.cpp: -------------------------------------------------------------------------------- 1 | // 本程序演示线程资源的回收(分离线程)。 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | void *thmain(void *arg); // 线程主函数。 9 | 10 | int main(int argc,char *argv[]) 11 | { 12 | pthread_t thid; 13 | 14 | pthread_attr_t attr; // 申明线程属性的数据结构。 15 | pthread_attr_init(&attr); // 初始化。 16 | pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED); // 设置线程的属性。 17 | // 创建线程。 18 | if (pthread_create(&thid,&attr,thmain,NULL)!=0) { printf("pthread_create failed.\n"); exit(-1); } 19 | pthread_attr_destroy(&attr); // 销毁数据结构。 20 | 21 | // pthread_detach(pthread_self()); 22 | 23 | sleep(5); 24 | 25 | int result=0; 26 | void *ret; 27 | printf("join...\n"); 28 | result=pthread_join(thid,&ret); printf("thid result=%d,ret=%ld\n",result,ret); 29 | printf("join ok.\n"); 30 | } 31 | 32 | void *thmain(void *arg) // 线程主函数。 33 | { 34 | // pthread_detach(pthread_self()); 35 | 36 | for (int ii=0;ii<3;ii++) 37 | { 38 | sleep(1); printf("pthmain sleep(%d) ok.\n",ii+1); 39 | } 40 | return (void *) 1; 41 | } 42 | -------------------------------------------------------------------------------- /pthread/book12.cpp: -------------------------------------------------------------------------------- 1 | // 本程序演示线程同步-互斥锁。 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | int var; 9 | 10 | pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER; // 声明互斥锁。 11 | 12 | void *thmain(void *arg); // 线程主函数。 13 | 14 | int main(int argc,char *argv[]) 15 | { 16 | // pthread_mutex_init(&mutex,NULL); // 初始化互斥锁。 17 | 18 | pthread_t thid1,thid2; 19 | 20 | // 创建线程。 21 | if (pthread_create(&thid1,NULL,thmain,NULL)!=0) { printf("pthread_create failed.\n"); exit(-1); } 22 | if (pthread_create(&thid2,NULL,thmain,NULL)!=0) { printf("pthread_create failed.\n"); exit(-1); } 23 | 24 | // 等待子线程退出。 25 | printf("join...\n"); 26 | pthread_join(thid1,NULL); 27 | pthread_join(thid2,NULL); 28 | printf("join ok.\n"); 29 | 30 | printf("var=%d\n",var); 31 | 32 | pthread_mutex_destroy(&mutex); // 销毁锁。 33 | } 34 | 35 | void *thmain(void *arg) // 线程主函数。 36 | { 37 | for (int ii=0;ii<1000000;ii++) 38 | { 39 | pthread_mutex_lock(&mutex); // 加锁。 40 | var++; 41 | pthread_mutex_unlock(&mutex); // 解锁。 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /tools/c/_tools_oracle.h: -------------------------------------------------------------------------------- 1 | #ifndef _TOOLS_ORACLE_H 2 | #define _TOOLS_ORACLE_H 3 | 4 | #include "_public.h" 5 | #include "_ooci.h" 6 | 7 | // 表的列(字段)信息的结构体。 8 | struct st_columns 9 | { 10 | char colname[31]; // 列名。 11 | char datatype[31]; // 列的数据类型,分为number、date和char三大类。 12 | int collen; // 列的长度,number固定20,date固定19,char的长度由表结构决定。 13 | int pkseq; // 如果列是主键的字段,存放主键字段的顺序,从1开始,不是主键取值0。 14 | }; 15 | 16 | // 获取表全部的列和主键列信息的类。 17 | class CTABCOLS 18 | { 19 | public: 20 | CTABCOLS(); 21 | 22 | int m_allcount; // 全部字段的个数。 23 | int m_pkcount; // 主键字段的个数。 24 | int m_maxcollen; // 全部列中最大的长度,这个成员是后来增加的,课程中并未提及。 25 | 26 | vector m_vallcols; // 存放全部字段信息的容器。 27 | vector m_vpkcols; // 存放主键字段信息的容器。 28 | 29 | char m_allcols[3001]; // 全部的字段名列表,以字符串存放,中间用半角的逗号分隔。 30 | char m_pkcols[301]; // 主键字段名列表,以字符串存放,中间用半角的逗号分隔。 31 | 32 | void initdata(); // 成员变量初始化。 33 | 34 | // 获取指定表的全部字段信息。 35 | bool allcols(connection *conn,char *tablename); 36 | 37 | // 获取指定表的主键字段信息。 38 | bool pkcols(connection *conn,char *tablename); 39 | }; 40 | 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /public/db/postgresql/deletetable.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 程序名:deletetable.cpp,此程序演示开发框架操作PostgreSQL数据库(删除表中的记录)。 3 | * 作者:吴从周。 4 | */ 5 | #include "_postgresql.h" // 开发框架操作PostgreSQL的头文件。 6 | 7 | int main(int argc,char *argv[]) 8 | { 9 | connection conn; // 数据库连接类 10 | 11 | // 登录数据库,返回值:0-成功,其它-失败。 12 | // 失败代码在conn.m_cda.rc中,失败描述在conn.m_cda.message中。 13 | if (conn.connecttodb("host=172.16.0.15 user=postgres password=pwdidc dbname=postgres port=5432","gbk")!=0) 14 | { 15 | printf("connect database failed.\n%s\n",conn.m_cda.message); return -1; 16 | } 17 | 18 | sqlstatement stmt(&conn); // 操作SQL语句的对象。 19 | 20 | // 执行SQL语句,一定要判断返回值,0-成功,其它-失败。 21 | // 失败代码在stmt.m_cda.rc中,失败描述在stmt.m_cda.message中。 22 | // 如果不需要绑定输入和输出变量,用stmt.execute()方法直接执行SQL语句,不需要stmt.prepare()。 23 | if (stmt.execute("delete from girls where id>=2 and id<=4") != 0) 24 | { 25 | printf("stmt.execute() failed.\n%s\n%s\n",stmt.m_sql,stmt.m_cda.message); return -1; 26 | } 27 | 28 | // 请注意,stmt.m_cda.rpc变量非常重要,它保存了SQL被执行后影响的记录数。 29 | printf("本次从girls表中删除了%ld条记录。\n",stmt.m_cda.rpc); 30 | 31 | // 提交事务 32 | conn.commit(); 33 | } 34 | 35 | -------------------------------------------------------------------------------- /public/demo/demo34.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 程序名:demo34.cpp,此程序演示开发框架的文件操作函数的用法 3 | * 作者:吴从周 4 | */ 5 | #include "../_public.h" 6 | 7 | int main() 8 | { 9 | // 删除文件。 10 | if (REMOVE("/project/public/lib_public.a")==false) 11 | { 12 | printf("REMOVE(/project/public/lib_public.a) %d:%s\n",errno,strerror(errno)); 13 | } 14 | 15 | // 重命名文件。 16 | if (RENAME("/project/public/lib_public.so","/tmp/aaa/bbb/ccc/lib_public.so")==false) 17 | { 18 | printf("RENAME(/project/public/lib_public.so) %d:%s\n",errno,strerror(errno)); 19 | } 20 | 21 | // 复制文件。 22 | if (COPY("/project/public/libftp.a","/tmp/root/aaa/bbb/ccc/libftp.a")==false) 23 | { 24 | printf("COPY(/project/public/libftp.a) %d:%s\n",errno,strerror(errno)); 25 | } 26 | 27 | // 获取文件的大小。 28 | printf("size=%d\n",FileSize("/project/public/_public.h")); 29 | 30 | // 重置文件的时间。 31 | UTime("/project/public/_public.h","2020-01-05 13:37:29"); 32 | 33 | // 获取文件的时间。 34 | char mtime[21]; memset(mtime,0,sizeof(mtime)); 35 | FileMTime("/project/public/_public.h",mtime,"yyyy-mm-dd hh24:mi:ss"); 36 | printf("mtime=%s\n",mtime); // 输出mtime=2020-01-05 13:37:29 37 | } 38 | 39 | -------------------------------------------------------------------------------- /public/socket/demo32.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 程序名:demo32.cpp,此程序是网络通信的服务端程序,用于演示同步通信的效率。 3 | * 作者:吴从周 4 | */ 5 | #include "../_public.h" 6 | 7 | int main(int argc,char *argv[]) 8 | { 9 | if (argc!=2) 10 | { 11 | printf("Using:./demo32 port\nExample:./demo32 5005\n\n"); return -1; 12 | } 13 | 14 | CTcpServer TcpServer; 15 | 16 | // 服务端初始化。 17 | if (TcpServer.InitServer(atoi(argv[1]))==false) 18 | { 19 | printf("TcpServer.InitServer(%s) failed.\n",argv[1]); return -1; 20 | } 21 | 22 | // 等待客户端的连接请求。 23 | if (TcpServer.Accept()==false) 24 | { 25 | printf("TcpServer.Accept() failed.\n"); return -1; 26 | } 27 | 28 | printf("客户端(%s)已连接。\n",TcpServer.GetIP()); 29 | 30 | char buffer[102400]; 31 | 32 | CLogFile logfile; 33 | logfile.Open("/tmp/demo32.log","a+"); 34 | 35 | // 与客户端通讯,接收客户端发过来的报文后,回复ok。 36 | while (1) 37 | { 38 | memset(buffer,0,sizeof(buffer)); 39 | if (TcpServer.Read(buffer)==false) break; // 接收客户端的请求报文。 40 | logfile.Write("接收:%s\n",buffer); 41 | 42 | strcpy(buffer,"ok"); 43 | if (TcpServer.Write(buffer)==false) break; // 向客户端发送响应结果。 44 | logfile.Write("发送:%s\n",buffer); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /public/socket/demo31.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 程序名:demo31.cpp,此程序是网络通信的客户端程序,用于演示异步通信(多进程)的效率。 3 | * 作者:吴从周。 4 | */ 5 | #include "../_public.h" 6 | 7 | int main(int argc,char *argv[]) 8 | { 9 | if (argc!=3) 10 | { 11 | printf("Using:./demo31 ip port\nExample:./demo31 192.168.174.132 5005\n\n"); return -1; 12 | } 13 | 14 | CTcpClient TcpClient; 15 | 16 | // 向服务端发起连接请求。 17 | if (TcpClient.ConnectToServer(argv[1],atoi(argv[2]))==false) 18 | { 19 | printf("TcpClient.ConnectToServer(%s,%s) failed.\n",argv[1],argv[2]); return -1; 20 | } 21 | 22 | char buffer[102400]; 23 | 24 | CLogFile logfile(1000); 25 | logfile.Open("/tmp/demo31.log","a+"); 26 | int pid=fork(); 27 | // 与服务端通讯,发送一个报文后等待回复,然后再发下一个报文。 28 | for (int ii=0;ii<1000000;ii++) 29 | { 30 | if (pid>0) 31 | { 32 | SPRINTF(buffer,sizeof(buffer),"这是第%d个超级女生,编号%03d。",ii+1,ii+1); 33 | if (TcpClient.Write(buffer)==false) break; // 向服务端发送请求报文。 34 | logfile.Write("发送:%s\n",buffer); 35 | } 36 | else 37 | { 38 | memset(buffer,0,sizeof(buffer)); 39 | if (TcpClient.Read(buffer)==false) break; // 接收服务端的回应报文。 40 | logfile.Write("接收:%s\n",buffer); 41 | } 42 | } 43 | } 44 | 45 | -------------------------------------------------------------------------------- /public/db/oracle/blobtofile.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 程序名:bolbtofile.cpp,此程序演示开发框架操作Oracle数据库。 3 | * 把Oracle的BLOB字段的内容提取到目前目录的pic_out.jpeg中。 4 | * 作者:吴从周。 5 | */ 6 | #include "_ooci.h" // 开发框架操作Oracle的头文件。 7 | 8 | int main(int argc,char *argv[]) 9 | { 10 | connection conn; // 数据库连接类 11 | 12 | // 连接数据库,返回值0-成功,其它-失败 13 | // 失败代码在conn.m_cda.rc中,失败描述在conn.m_cda.message中。 14 | if (conn.connecttodb("scott/tiger@snorcl11g_132","Simplified Chinese_China.AL32UTF8") != 0) 15 | { 16 | printf("connect database failed.\n%s\n",conn.m_cda.message); return -1; 17 | } 18 | 19 | sqlstatement stmt(&conn); // SQL语句操作类 20 | 21 | // 不需要判断返回值 22 | stmt.prepare("select pic from girls where id=1"); 23 | stmt.bindblob(); 24 | 25 | // 执行SQL语句,一定要判断返回值,0-成功,其它-失败。 26 | if (stmt.execute() != 0) 27 | { 28 | printf("stmt.execute() failed.\n%s\n%s\n",stmt.m_sql,stmt.m_cda.message); return -1; 29 | } 30 | 31 | // 获取一条记录,一定要判断返回值,0-成功,1403-无记录,其它-失败。 32 | if (stmt.next() != 0) return 0; 33 | 34 | // 把BLOB字段中的内容写入磁盘文件,一定要判断返回值,0-成功,其它-失败。 35 | if (stmt.lobtofile((char *)"pic_out.jpeg") != 0) 36 | { 37 | printf("stmt.lobtofile() failed.\n%s\n",stmt.m_cda.message); return -1; 38 | } 39 | } 40 | 41 | -------------------------------------------------------------------------------- /public/db/oracle/clobtofile.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 程序名:clobtofile.cpp,此程序演示开发框架操作Oracle数据库。 3 | * 把Oracle的CLOB字段的内容提取到目前目录的memo_out.txt中。 4 | * 作者:吴从周。 5 | */ 6 | #include "_ooci.h" // 开发框架操作Oracle的头文件。 7 | 8 | int main(int argc,char *argv[]) 9 | { 10 | connection conn; // 数据库连接类 11 | 12 | // 连接数据库,返回值0-成功,其它-失败 13 | // 失败代码在conn.m_cda.rc中,失败描述在conn.m_cda.message中。 14 | if (conn.connecttodb("scott/tiger@snorcl11g_132","Simplified Chinese_China.AL32UTF8") != 0) 15 | { 16 | printf("connect database failed.\n%s\n",conn.m_cda.message); return -1; 17 | } 18 | 19 | sqlstatement stmt(&conn); // SQL语句操作类 20 | 21 | // 不需要判断返回值 22 | stmt.prepare("select memo from girls where id=1"); 23 | stmt.bindclob(); 24 | 25 | // 执行SQL语句,一定要判断返回值,0-成功,其它-失败。 26 | if (stmt.execute() != 0) 27 | { 28 | printf("stmt.execute() failed.\n%s\n%s\n",stmt.m_sql,stmt.m_cda.message); return -1; 29 | } 30 | 31 | // 获取一条记录,一定要判断返回值,0-成功,1403-无记录,其它-失败。 32 | if (stmt.next() != 0) return 0; 33 | 34 | // 把CLOB字段中的内容写入磁盘文件,一定要判断返回值,0-成功,其它-失败。 35 | if (stmt.lobtofile((char *)"memo_out.txt") != 0) 36 | { 37 | printf("stmt.lobtofile() failed.\n%s\n",stmt.m_cda.message); return -1; 38 | } 39 | } 40 | 41 | -------------------------------------------------------------------------------- /public/db/oracle/counttable.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 程序名:counttable.cpp,此程序演示开发框架操作Oracle数据库(查询表中的记录数)。 3 | * 作者:吴从周。 4 | */ 5 | #include "_ooci.h" // 开发框架操作Oracle的头文件。 6 | 7 | int main(int argc,char *argv[]) 8 | { 9 | connection conn; // 数据库连接类 10 | 11 | // 登录数据库,返回值:0-成功,其它-失败。 12 | // 失败代码在conn.m_cda.rc中,失败描述在conn.m_cda.message中。 13 | if (conn.connecttodb("scott/tiger@snorcl11g_132","Simplified Chinese_China.AL32UTF8")!=0) 14 | { 15 | printf("connect database failed.\n%s\n",conn.m_cda.message); return -1; 16 | } 17 | 18 | sqlstatement stmt(&conn); // 操作SQL语句的对象。 19 | 20 | int icount=0; // 用于存放查询结果的记录数。 21 | 22 | // 准备查询表的SQL语句,把查询条件直接写在SQL语句中,没有采用绑定输入变量的方法。 23 | stmt.prepare("select count(*) from girls where id>=2 and id<=4"); 24 | // prepare方法不需要判断返回值。 25 | // 为SQL语句绑定输出变量的地址,bindout方法不需要判断返回值。 26 | stmt.bindout(1,&icount); 27 | 28 | // 执行SQL语句,一定要判断返回值,0-成功,其它-失败。 29 | // 失败代码在stmt.m_cda.rc中,失败描述在stmt.m_cda.message中。 30 | if (stmt.execute() != 0) 31 | { 32 | printf("stmt.execute() failed.\n%s\n%s\n",stmt.m_sql,stmt.m_cda.message); return -1; 33 | } 34 | 35 | // 本程序执行的是查询语句,执行stmt.execute()后,将会在数据库的缓冲区中产生一个结果集。 36 | // 但是,在本程序中,结果集永远只有一条记录,调用stmt.next()一次就行,不需要循环。 37 | stmt.next(); 38 | 39 | printf("girls表中符合条件的记录数是%d。\n",icount); 40 | } 41 | 42 | -------------------------------------------------------------------------------- /pthread/book1.cpp: -------------------------------------------------------------------------------- 1 | // 本程序演示线程的创建和终止。 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | int var=0; 9 | 10 | void *thmain1(void *arg); // 线程主函数。 11 | void *thmain2(void *arg); // 线程主函数。 12 | 13 | int main(int argc,char *argv[]) 14 | { 15 | pthread_t thid1=0; // 线程id typedef unsigned long pthread_t 16 | pthread_t thid2=0; // 线程id typedef unsigned long pthread_t 17 | 18 | // 创建线程。 19 | if (pthread_create(&thid1,NULL,thmain1,NULL)!=0) { printf("pthread_create failed.\n"); exit(-1); } 20 | if (pthread_create(&thid2,NULL,thmain2,NULL)!=0) { printf("pthread_create failed.\n"); exit(-1); } 21 | 22 | // 等待子线程退出。 23 | printf("join...\n"); 24 | pthread_join(thid1,NULL); 25 | pthread_join(thid2,NULL); 26 | printf("join ok.\n"); 27 | } 28 | 29 | void fun1() 30 | { return;} 31 | 32 | void *thmain1(void *arg) // 线程主函数。 33 | { 34 | for (int ii=0;ii<5;ii++) 35 | { 36 | var=ii+1; 37 | sleep(1); printf("pthmain1 sleep(%d) ok.\n",var); 38 | if (ii==2) fun1(); 39 | } 40 | } 41 | 42 | void fun2() 43 | { pthread_exit(0);} 44 | 45 | void *thmain2(void *arg) // 线程主函数。 46 | { 47 | for (int ii=0;ii<5;ii++) 48 | { 49 | sleep(1); printf("pthmain2 sleep(%d) ok.\n",var); 50 | if (ii==2) fun2(); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /public/db/oracle/createtable.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 程序名:createtable.cpp,此程序演示开发框架操作Oracle数据库(创建表)。 3 | * 作者:吴从周。 4 | */ 5 | #include "_ooci.h" // 开发框架操作Oracle的头文件。 6 | 7 | int main(int argc,char *argv[]) 8 | { 9 | connection conn; // 数据库连接类 10 | 11 | // 登录数据库,返回值:0-成功,其它-失败。 12 | // 失败代码在conn.m_cda.rc中,失败描述在conn.m_cda.message中。 13 | if (conn.connecttodb("scott/tiger@snorcl11g_132","Simplified Chinese_China.AL32UTF8")!=0) 14 | { 15 | printf("connect database failed.\n%s\n",conn.m_cda.message); return -1; 16 | } 17 | 18 | sqlstatement stmt(&conn); // 操作SQL语句的对象。 19 | 20 | // 准备创建表的SQL语句。 21 | // 超女表girls,超女编号id,超女姓名name,体重weight,报名时间btime,超女说明memo,超女图片pic。 22 | stmt.prepare("\ 23 | create table girls(id number(10),\ 24 | name varchar2(30),\ 25 | weight number(8,2),\ 26 | btime date,\ 27 | memo clob,\ 28 | pic blob,\ 29 | primary key (id))"); 30 | // prepare方法不需要判断返回值。 31 | 32 | // 执行SQL语句,一定要判断返回值,0-成功,其它-失败。 33 | // 失败代码在stmt.m_cda.rc中,失败描述在stmt.m_cda.message中。 34 | if (stmt.execute() != 0) 35 | { 36 | printf("stmt.execute() failed.\n%s\n%s\n",stmt.m_sql,stmt.m_cda.message); return -1; 37 | } 38 | 39 | printf("create table girls ok.\n"); 40 | } 41 | 42 | -------------------------------------------------------------------------------- /public/db/postgresql/counttable.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 程序名:counttable.cpp,此程序演示开发框架操作PostgreSQL数据库(查询表中的记录数)。 3 | * 作者:吴从周。 4 | */ 5 | #include "_postgresql.h" // 开发框架操作PostgreSQL的头文件。 6 | 7 | int main(int argc,char *argv[]) 8 | { 9 | connection conn; // 数据库连接类 10 | 11 | // 登录数据库,返回值:0-成功,其它-失败。 12 | // 失败代码在conn.m_cda.rc中,失败描述在conn.m_cda.message中。 13 | if (conn.connecttodb("host=172.16.0.15 user=postgres password=pwdidc dbname=postgres port=5432","gbk")!=0) 14 | { 15 | printf("connect database failed.\n%s\n",conn.m_cda.message); return -1; 16 | } 17 | 18 | sqlstatement stmt(&conn); // 操作SQL语句的对象。 19 | 20 | int icount=0; // 用于存放查询结果的记录数。 21 | 22 | // 准备查询表的SQL语句,把查询条件直接写在SQL语句中,没有采用绑定输入变量的方法。 23 | stmt.prepare("select count(*) from girls where id>=2 and id<=4"); 24 | // prepare方法不需要判断返回值。 25 | // 为SQL语句绑定输出变量的地址,bindout方法不需要判断返回值。 26 | stmt.bindout(1,&icount); 27 | 28 | // 执行SQL语句,一定要判断返回值,0-成功,其它-失败。 29 | // 失败代码在stmt.m_cda.rc中,失败描述在stmt.m_cda.message中。 30 | if (stmt.execute() != 0) 31 | { 32 | printf("stmt.execute() failed.\n%s\n%s\n",stmt.m_sql,stmt.m_cda.message); return -1; 33 | } 34 | 35 | // 本程序执行的是查询语句,执行stmt.execute()后,将会在数据库的缓冲区中产生一个结果集。 36 | // 但是,在本程序中,结果集永远只有一条记录,调用stmt.next()一次就行,不需要循环。 37 | stmt.next(); 38 | 39 | printf("girls表中符合条件的记录数是%d。\n",icount); 40 | } 41 | 42 | -------------------------------------------------------------------------------- /public/db/mysql/deletetable.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 程序名:deletetable.cpp,此程序演示开发框架操作MySQL数据库(删除表中的记录)。 3 | * 作者:吴从周。 4 | */ 5 | 6 | #include "_mysql.h" // 开发框架操作MySQL的头文件。 7 | 8 | int main(int argc,char *argv[]) 9 | { 10 | connection conn; // 数据库连接类。 11 | 12 | // 登录数据库,返回值:0-成功;其它是失败,存放了MySQL的错误代码。 13 | // 失败代码在conn.m_cda.rc中,失败描述在conn.m_cda.message中。 14 | if (conn.connecttodb("127.0.0.1,root,mysqlpwd,mysql,3306","utf8")!=0) 15 | { 16 | printf("connect database failed.\n%s\n",conn.m_cda.message); return -1; 17 | } 18 | 19 | sqlstatement stmt(&conn); // 操作SQL语句的对象。 20 | 21 | int iminid,imaxid; // 删除条件最小和最大的id。 22 | 23 | // 准备删除表的SQL语句。 24 | stmt.prepare("delete from girls where id>=:1 and id<=:2"); 25 | // 为SQL语句绑定输入变量的地址,bindin方法不需要判断返回值。 26 | stmt.bindin(1,&iminid); 27 | stmt.bindin(2,&imaxid); 28 | 29 | iminid=1; // 指定待删除记录的最小id的值。 30 | imaxid=3; // 指定待删除记录的最大id的值。 31 | 32 | // 执行SQL语句,一定要判断返回值,0-成功,其它-失败。 33 | // 失败代码在stmt.m_cda.rc中,失败描述在stmt.m_cda.message中。 34 | if (stmt.execute() != 0) 35 | { 36 | printf("stmt.execute() failed.\n%s\n%s\n",stmt.m_sql,stmt.m_cda.message); return -1; 37 | } 38 | 39 | // 请注意,stmt.m_cda.rpc变量非常重要,它保存了SQL被执行后影响的记录数。 40 | printf("本次删除了girls表%ld条记录。\n",stmt.m_cda.rpc); 41 | 42 | conn.commit(); // 提交数据库事务。 43 | 44 | return 0; 45 | } 46 | 47 | -------------------------------------------------------------------------------- /tools/c/procctl.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | int main(int argc,char *argv[]) 9 | { 10 | if (argc<3) 11 | { 12 | printf("Using:./procctl timetvl program argv ...\n"); 13 | printf("Example:/project/tools1/bin/procctl 5 /usr/bin/tar zcvf /tmp/tmp.tgz /usr/include\n\n"); 14 | 15 | printf("本程序是服务程序的调度程序,周期性启动服务程序或shell脚本。\n"); 16 | printf("timetvl 运行周期,单位:秒。被调度的程序运行结束后,在timetvl秒后会被procctl重新启动。\n"); 17 | printf("program 被调度的程序名,必须使用全路径。\n"); 18 | printf("argvs 被调度的程序的参数。\n"); 19 | printf("注意,本程序不会被kill杀死,但可以用kill -9强行杀死。\n\n\n"); 20 | 21 | return -1; 22 | } 23 | 24 | // 关闭信号和IO,本程序不希望被打扰。 25 | for (int ii=0;ii<64;ii++) 26 | { 27 | signal(ii,SIG_IGN); close(ii); 28 | } 29 | 30 | // 生成子进程,父进程退出,让程序运行在后台,由系统1号进程托管。 31 | if (fork()!=0) exit(0); 32 | 33 | // 启用SIGCHLD信号,让父进程可以wait子进程退出的状态。 34 | signal(SIGCHLD,SIG_DFL); 35 | 36 | char *pargv[argc]; 37 | for (int ii=2;ii西施10true3068.521000000Barcelona"); 25 | 26 | GetXMLBuffer(buffer,"name",stplayer.name,50); 27 | GetXMLBuffer(buffer,"no",stplayer.no,5); 28 | GetXMLBuffer(buffer,"striker",&stplayer.striker); 29 | GetXMLBuffer(buffer,"age",&stplayer.age); 30 | GetXMLBuffer(buffer,"weight",&stplayer.weight); 31 | GetXMLBuffer(buffer,"sal",&stplayer.sal); 32 | GetXMLBuffer(buffer,"club",stplayer.club,50); 33 | 34 | printf("name=%s,no=%s,striker=%d,age=%d,weight=%.1f,sal=%ld,club=%s\n",\ 35 | stplayer.name,stplayer.no,stplayer.striker,stplayer.age,\ 36 | stplayer.weight,stplayer.sal,stplayer.club); 37 | // 输出结果:name=messi,no=10,striker=1,age=30,weight=68.5,sal=21000000,club=Barcelona 38 | } 39 | 40 | -------------------------------------------------------------------------------- /public/_cmpublic.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************************** 2 | * 程序名:_cmpublic.h,此程序是开发框架公用头文件,包含了应用开发常用的头文件。 3 | * 作者:吴从周 4 | *****************************************************************************************/ 5 | 6 | #ifndef _cmpublic_H 7 | #define _cmpublic_H 8 | 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 | #include 23 | #include 24 | #include 25 | #include 26 | #include 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 | #include 41 | 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | #include 48 | #include 49 | #include 50 | 51 | // 采用stl标准库的命名空间std 52 | using namespace std; 53 | 54 | #endif 55 | 56 | -------------------------------------------------------------------------------- /public/demo/demo20.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 程序名:demo20.cpp,此程序演示开发框架拆分字符串的类CCmdStr的使用。 3 | * 作者:吴从周 4 | */ 5 | #include "../_public.h" 6 | 7 | // 用于存放足球运动员资料的结构体。 8 | struct st_player 9 | { 10 | char name[51]; // 姓名 11 | char no[6]; // 球衣号码 12 | bool striker; // 场上位置是否是前锋,true-是;false-不是。 13 | int age; // 年龄 14 | double weight; // 体重,kg。 15 | long sal; // 年薪,欧元。 16 | char club[51]; // 效力的俱乐部 17 | }stplayer; 18 | 19 | int main() 20 | { 21 | memset(&stplayer,0,sizeof(struct st_player)); 22 | 23 | char buffer[301]; 24 | STRCPY(buffer,sizeof(buffer),"messi ,10,true,30,68.5,2100000,Barcelona"); 25 | 26 | CCmdStr CmdStr; 27 | CmdStr.SplitToCmd(buffer,","); // 拆分buffer 28 | CmdStr.GetValue(0, stplayer.name,50); // 获取姓名 29 | CmdStr.GetValue(1, stplayer.no,5); // 获取球衣号码 30 | CmdStr.GetValue(2,&stplayer.striker); // 场上位置 31 | CmdStr.GetValue(3,&stplayer.age); // 获取年龄 32 | CmdStr.GetValue(4,&stplayer.weight); // 获取体重 33 | CmdStr.GetValue(5,&stplayer.sal); // 获取年薪,欧元。 34 | CmdStr.GetValue(6, stplayer.club,50); // 获取效力的俱乐部 35 | 36 | printf("name=%s,no=%s,striker=%d,age=%d,weight=%.1f,sal=%ld,club=%s\n",\ 37 | stplayer.name,stplayer.no,stplayer.striker,stplayer.age,\ 38 | stplayer.weight,stplayer.sal,stplayer.club); 39 | // 输出结果:name=messi,no=10,striker=1,age=30,weight=68.5,sal=21000000,club=Barcelona 40 | } 41 | 42 | -------------------------------------------------------------------------------- /trebox/_cmpublic.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************************** 2 | * 程序名:_cmpublic.h,此程序是开发框架公用头文件,包含了应用开发常用的头文件。 3 | * 作者:吴从周 4 | *****************************************************************************************/ 5 | 6 | #ifndef _cmpublic_H 7 | #define _cmpublic_H 8 | 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 | #include 23 | #include 24 | #include 25 | #include 26 | #include 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 | #include 41 | 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | #include 48 | #include 49 | #include 50 | 51 | // 采用stl标准库的命名空间std 52 | using namespace std; 53 | 54 | #endif 55 | 56 | -------------------------------------------------------------------------------- /public/demo/demo39.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 程序名:demo39.cpp,此程序演示开发框架中采用CFile类生成数据文件的用法。 3 | * 作者:吴从周 4 | */ 5 | #include "../_public.h" 6 | 7 | int main() 8 | { 9 | CFile File; 10 | 11 | char strLocalTime[21]; // 用于存放系统当前的时间,格式yyyymmddhh24miss。 12 | memset(strLocalTime,0,sizeof(strLocalTime)); 13 | LocalTime(strLocalTime,"yyyymmddhh24miss"); // 获取系统当前时间。 14 | 15 | // 生成绝对路径的文件名,目录/tmp/data,文件名:前缀(surfdata_)+时间+后缀(.xml)。 16 | char strFileName[301]; 17 | SNPRINTF(strFileName,sizeof(strFileName),300,"/tmp/data/surfdata_%s.xml",strLocalTime); 18 | 19 | // 采用OpenForRename创建文件,实际创建的文件名例如/tmp/data/surfdata_20200101123000.xml.tmp。 20 | if (File.OpenForRename(strFileName,"w")==false) 21 | { 22 | printf("File.OpenForRename(%s) failed.\n",strFileName); return -1; 23 | } 24 | 25 | // 这里可以插入向文件写入数据的代码。 26 | // 写入文本数据用Fprintf方法,写入二进制数据用Fwrite方法。 27 | 28 | // 向文件中写入两行超女数据。 29 | File.Fprintf("\n"\ 30 | "妲已28火辣漂亮商要亡,关我什么事。\n"\ 31 | "西施25火辣漂亮1、中国排名第一的美女;\n"\ 32 | "2、男朋友是范蠡;\n"\ 33 | "3、老公是夫差,被勾践弄死了。\n"\ 34 | "\n"); 35 | 36 | //sleep(30); // 停止30秒,用ls /tmp/data/*.tmp可以看到生成的临时文件。 37 | 38 | // 关闭文件指针,并把临时文件名改为正式的文件名。 39 | // 注意,不能用File.Close(),因为Close方法是关闭文件指针,并删除临时文件。 40 | // CFile类的析构函数调用的是Close方法。 41 | File.CloseAndRename(); 42 | } 43 | 44 | -------------------------------------------------------------------------------- /public/socket/demo05.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 程序名:demo05.cpp,此程序用于演示不粘包的socket客户端。 3 | * 作者:吴从周。 4 | */ 5 | #include "../_public.h" 6 | 7 | int main(int argc,char *argv[]) 8 | { 9 | if (argc!=3) 10 | { 11 | printf("Using:./demo05 ip port\nExample:./demo05 127.0.0.1 5005\n\n"); return -1; 12 | } 13 | 14 | // 第1步:创建客户端的socket。 15 | int sockfd; 16 | if ( (sockfd = socket(AF_INET,SOCK_STREAM,0))==-1) { perror("socket"); return -1; } 17 | 18 | // 第2步:向服务器发起连接请求。 19 | struct hostent* h; 20 | if ( (h = gethostbyname(argv[1])) == 0 ) // 指定服务端的ip地址。 21 | { printf("gethostbyname failed.\n"); close(sockfd); return -1; } 22 | struct sockaddr_in servaddr; 23 | memset(&servaddr,0,sizeof(servaddr)); 24 | servaddr.sin_family = AF_INET; 25 | servaddr.sin_port = htons(atoi(argv[2])); // 指定服务端的通讯端口。 26 | memcpy(&servaddr.sin_addr,h->h_addr,h->h_length); 27 | if (connect(sockfd, (struct sockaddr *)&servaddr,sizeof(servaddr)) != 0) // 向服务端发起连接清求。 28 | { perror("connect"); close(sockfd); return -1; } 29 | 30 | char buffer[1024]; 31 | 32 | // 第3步:与服务端通讯,连续发送1000个报文。 33 | for (int ii=0;ii<1000;ii++) 34 | { 35 | memset(buffer,0,sizeof(buffer)); 36 | sprintf(buffer,"这是第%d个超级女生,编号%03d。",ii+1,ii+1); 37 | 38 | if (TcpWrite(sockfd,buffer,strlen(buffer))==false) break; // 向服务端发送请求报文。 39 | 40 | printf("发送:%s\n",buffer); 41 | } 42 | 43 | // 第4步:关闭socket,释放资源。 44 | close(sockfd); 45 | } 46 | 47 | -------------------------------------------------------------------------------- /pthread/book6.cpp: -------------------------------------------------------------------------------- 1 | // 本程序演示线程资源的回收,用pthread_join非分离的线程。 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | void *thmain1(void *arg); // 线程主函数。 9 | void *thmain2(void *arg); // 线程主函数。 10 | 11 | int main(int argc,char *argv[]) 12 | { 13 | pthread_t thid1,thid2; 14 | 15 | // 创建线程。 16 | if (pthread_create(&thid1,NULL,thmain1,NULL)!=0) { printf("pthread_create failed.\n"); exit(-1); } 17 | if (pthread_create(&thid2,NULL,thmain2,NULL)!=0) { printf("pthread_create failed.\n"); exit(-1); } 18 | sleep(10); 19 | void *ret; 20 | printf("join...\n"); 21 | int result=0; 22 | result=pthread_join(thid2,&ret); printf("thid2 result=%d,ret=%ld\n",result,ret); 23 | result=pthread_join(thid1,&ret); printf("thid1 result=%d,ret=%ld\n",result,ret); 24 | ret=0; 25 | result=pthread_join(thid2,&ret); printf("thid2 result=%d,ret=%ld\n",result,ret); 26 | result=pthread_join(thid1,&ret); printf("thid1 result=%d,ret=%ld\n",result,ret); 27 | printf("join ok.\n"); 28 | } 29 | 30 | void *thmain1(void *arg) // 线程1主函数。 31 | { 32 | for (int ii=0;ii<3;ii++) 33 | { 34 | sleep(1); printf("pthmain1 sleep(%d) ok.\n",ii+1); 35 | } 36 | return (void *) 1; 37 | } 38 | 39 | void *thmain2(void *arg) // 线程2主函数。 40 | { 41 | for (int ii=0;ii<5;ii++) 42 | { 43 | sleep(1); printf("pthmain2 sleep(%d) ok.\n",ii+1); 44 | } 45 | return (void *) 2; 46 | } 47 | -------------------------------------------------------------------------------- /public/db/postgresql/createtable.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 程序名:createtable.cpp,此程序演示开发框架操作PostgreSQL数据库(创建表)。 3 | * 作者:吴从周。 4 | */ 5 | #include "_postgresql.h" // 开发框架操作PostgreSQL的头文件。 6 | 7 | int main(int argc,char *argv[]) 8 | { 9 | connection conn; // 数据库连接池。 10 | 11 | // 登录数据库,返回值:0-成功,其它-失败。 12 | // 失败代码在conn.m_cda.rc中,失败描述在conn.m_cda.message中。 13 | if (conn.connecttodb("host=172.16.0.15 user=postgres password=pwdidc dbname=postgres port=5432","gbk")!=0) 14 | { 15 | printf("connect database failed.\n%s\n",conn.m_cda.message); return -1; 16 | } 17 | 18 | sqlstatement stmt(&conn); // 操作SQL语句的对象。 19 | 20 | // 准备创建表的SQL语句。 21 | // 超女表girls,超女编号id,超女姓名name,体重weight,报名时间btime,超女说明memo,超女图片pic。 22 | stmt.prepare("\ 23 | create table girls(id int,\ 24 | name varchar(30),\ 25 | weight numeric(8,2),\ 26 | btime timestamp,\ 27 | memo text,\ 28 | pic bytea,\ 29 | primary key (id))"); 30 | // prepare方法不需要判断返回值。 31 | 32 | // 执行SQL语句,一定要判断返回值,0-成功,其它-失败。 33 | // 失败代码在stmt.m_cda.rc中,失败描述在stmt.m_cda.message中。 34 | if (stmt.execute() != 0) 35 | { 36 | printf("stmt.execute() failed.\n%s\n%s\n",stmt.m_sql,stmt.m_cda.message); return -1; 37 | } 38 | 39 | // 注意,在postgresql数据库中,创建表也要提交事务,和Oracle、MySQL数据库不同。 40 | conn.commit(); 41 | 42 | printf("create table girls ok.\n"); 43 | } 44 | 45 | -------------------------------------------------------------------------------- /public/demo/demo42.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 程序名:demo42.cpp,此程序演示采用开发框架的CLogFile类记录程序的运行日志。 3 | * 本程序修改demo40.cpp把输出的printf语句改为写日志文件。 4 | * 作者:吴从周 5 | */ 6 | #include "../_public.h" 7 | 8 | int main() 9 | { 10 | CLogFile logfile; 11 | 12 | // 打开日志文件,如果"/tmp/log"不存在,就创建它,但是要确保当前用户具备创建目录的权限。 13 | if (logfile.Open("/tmp/log/demo42.log")==false) 14 | { printf("logfile.Open(/tmp/log/demo42.log) failed.\n"); return -1; } 15 | 16 | logfile.Write("demo42程序开始运行。\n"); 17 | 18 | CDir Dir; 19 | 20 | // 扫描/tmp/data目录下文件名匹配"surfdata_*.xml"的文件。 21 | if (Dir.OpenDir("/tmp/data","surfdata_*.xml")==false) 22 | { logfile.Write("Dir.OpenDir(/tmp/data) failed.\n"); return -1; } 23 | 24 | CFile File; 25 | 26 | while (Dir.ReadDir()==true) 27 | { 28 | logfile.Write("处理文件%s...",Dir.m_FullFileName); 29 | 30 | if (File.Open(Dir.m_FullFileName,"r")==false) 31 | { logfile.WriteEx("failed.File.Open(%s) failed.\n",Dir.m_FullFileName); return -1; } 32 | 33 | char strBuffer[301]; 34 | 35 | while (true) 36 | { 37 | memset(strBuffer,0,sizeof(strBuffer)); 38 | if (File.FFGETS(strBuffer,300,"")==false) break; // 行内容以""结束。 39 | 40 | // logfile.Write("strBuffer=%s",strBuffer); 41 | 42 | // 这里可以插入解析xml字符串并把数据写入数据库的代码。 43 | } 44 | 45 | 46 | // 处理完文件中的数据后,关闭文件指针,并删除文件。 47 | File.CloseAndRemove(); 48 | 49 | logfile.WriteEx("ok\n"); 50 | } 51 | 52 | logfile.Write("demo42程序运行结束。\n"); 53 | } 54 | 55 | -------------------------------------------------------------------------------- /public/demo/demo21.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 程序名:demo21.cpp,此程序演示开发框架中字符串替换UpdateStr函数的使用。 3 | * 作者:吴从周 4 | */ 5 | #include "../_public.h" 6 | 7 | int main() 8 | { 9 | char str[301]; 10 | 11 | STRCPY(str,sizeof(str),"name:messi,no:10,job:striker."); 12 | UpdateStr(str,":","="); // 把冒号替换成等号。 13 | printf("str=%s=\n",str); // 出输结果是str1=name=messi,no=10,job=striker.= 14 | 15 | STRCPY(str,sizeof(str),"name:messi,no:10,job:striker."); 16 | UpdateStr(str,"name:",""); // 把"name:"替换成"",相当于删除内容"name:"。 17 | printf("str=%s=\n",str); // 出输结果是str1=messi,no:10,job:striker.= 18 | 19 | STRCPY(str,sizeof(str),"messi----10----striker"); 20 | UpdateStr(str,"--","-",false); // 把两个"--"替换成一个"-",bLoop参数为false。 21 | printf("str=%s=\n",str); // 出输结果是str1=messi--10--striker= 22 | 23 | STRCPY(str,sizeof(str),"messi----10----striker"); 24 | UpdateStr(str,"--","-",true); // 把两个"--"替换成一个"-",bLoop参数为true。 25 | printf("str=%s=\n",str); // 出输结果是str1=messi-10-striker= 26 | 27 | STRCPY(str,sizeof(str),"messi-10-striker"); 28 | UpdateStr(str,"-","--",false); // 把一个"-"替换成两个"--",bLoop参数为false。 29 | printf("str=%s=\n",str); // 出输结果是str1=messi--10--striker= 30 | 31 | STRCPY(str,sizeof(str),"messi-10-striker"); 32 | 33 | // 以下代码把"-"替换成"--",bloop参数为true,存在逻辑错误,UpdateStr将不执行替换。 34 | UpdateStr(str,"-","--",true); // 把一个"-"替换成两个"--",bloop参数为true。 35 | printf("str=%s=\n",str); // 出输结果是str1=messi-10-striker= 36 | } 37 | 38 | -------------------------------------------------------------------------------- /public/socket/demo33.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 程序名:demo33.cpp,此程序是网络通信的客户端程序,用于演示异步通信(poll)效率。 3 | * 作者:吴从周。 4 | */ 5 | #include "../_public.h" 6 | 7 | int main(int argc,char *argv[]) 8 | { 9 | if (argc!=3) 10 | { 11 | printf("Using:./demo33 ip port\nExample:./demo33 192.168.174.133 5005\n\n"); return -1; 12 | } 13 | 14 | CTcpClient TcpClient; 15 | 16 | // 向服务端发起连接请求。 17 | if (TcpClient.ConnectToServer(argv[1],atoi(argv[2]))==false) 18 | { 19 | printf("TcpClient.ConnectToServer(%s,%s) failed.\n",argv[1],argv[2]); return -1; 20 | } 21 | 22 | char buffer[102400]; 23 | int ibuflen=0; 24 | 25 | CLogFile logfile(1000); 26 | logfile.Open("/tmp/demo33.log","a+"); 27 | 28 | int jj=0; 29 | 30 | // 与服务端通讯,发送一个报文后等待回复,然后再发下一个报文。 31 | for (int ii=0;ii<1000000;ii++) 32 | { 33 | SPRINTF(buffer,sizeof(buffer),"这是第%d个超级女生,编号%03d。",ii+1,ii+1); 34 | if (TcpClient.Write(buffer)==false) break; // 向服务端发送请求报文。 35 | logfile.Write("发送:%s\n",buffer); 36 | 37 | // 接收服务端的回应报文。 38 | while (true) 39 | { 40 | memset(buffer,0,sizeof(buffer)); 41 | if (TcpRead(TcpClient.m_connfd,buffer,&ibuflen,-1)==false) break; 42 | logfile.Write("接收:%s\n",buffer); 43 | jj++; 44 | } 45 | } 46 | 47 | // 接收服务端的回应报文。 48 | while (jj<1000000) 49 | { 50 | memset(buffer,0,sizeof(buffer)); 51 | if (TcpRead(TcpClient.m_connfd,buffer,&ibuflen)==false) break; 52 | logfile.Write("接收:%s\n",buffer); 53 | jj++; 54 | } 55 | } 56 | 57 | -------------------------------------------------------------------------------- /trebox/CLogFile.cpp: -------------------------------------------------------------------------------- 1 | #include "_public.h" 2 | 3 | // 日志文件操作类 4 | class CLogFile 5 | { 6 | public: 7 | FILE *m_tracefp; // 日志文件指针。 8 | char m_filename[301]; // 日志文件名,建议采用绝对路径。 9 | char m_openmode[11]; // 日志文件的打开方式,一般采用"a+"。 10 | bool m_bEnBuffer; // 写入日志时,是否启用操作系统的缓冲机制,缺省不启用。 11 | bool m_bBackup; // 是否自动切换,日志文件大小超过m_MaxLogSize将自动切换,缺省启用。 12 | long m_MaxLogSize; // 最大日志文件的大小,单位M,缺省100M。 13 | // pthread_spinlock_t spin; // 初学暂时不要关心这行代码。 14 | 15 | // 构造函数。 16 | // MaxLogSize:最大日志文件的大小,单位M,缺省100M,最小为10M。 17 | CLogFile(const long MaxLogSize=100); 18 | 19 | // 打开日志文件。 20 | // filename:日志文件名,建议采用绝对路径,如果文件名中的目录不存在,就先创建目录。 21 | // openmode:日志文件的打开方式,与fopen库函数打开文件的方式相同,缺省值是"a+"。 22 | // bBackup:是否自动切换,true-切换,false-不切换,在多进程的服务程序中,如果多个进程共用一个日志文件,bBackup必须为false。 23 | // bEnBuffer:是否启用文件缓冲机制,true-启用,false-不启用,如果启用缓冲区,那么写进日志文件中的内容不会立即写入文件,缺省是不启用。 24 | bool Open(const char *filename,const char *openmode=0,bool bBackup=true,bool bEnBuffer=false); 25 | 26 | // 如果日志文件大于m_MaxLogSize的值,就把当前的日志文件名改为历史日志文件名,再创建新的当前日志文件。 27 | // 备份后的文件会在日志文件名后加上日期时间,如/tmp/log/filetodb.log.20200101123025。 28 | // 注意,在多进程的程序中,日志文件不可切换,多线的程序中,日志文件可以切换。 29 | bool BackupLogFile(); 30 | 31 | // 把内容写入日志文件,fmt是可变参数,使用方法与printf库函数相同。 32 | // Write方法会写入当前的时间,WriteEx方法不写时间。 33 | bool Write(const char *fmt,...); 34 | bool WriteEx(const char *fmt,...); 35 | 36 | // 关闭日志文件 37 | void Close(); 38 | 39 | ~CLogFile(); // 析构函数会调用Close方法。 40 | }; -------------------------------------------------------------------------------- /public/demo/demo45.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 程序名:demo45.cpp,此程序演示采用开发框架的CIniFile类加载参数文件。 3 | * 作者:吴从周 4 | */ 5 | #include "../_public.h" 6 | 7 | // 用于存放本程序运行参数的数据结构。 8 | struct st_args 9 | { 10 | char logpath[301]; 11 | char connstr[101]; 12 | char datapath[301]; 13 | char serverip[51]; 14 | int port; 15 | bool online; 16 | }stargs; 17 | 18 | int main(int argc,char *argv[]) 19 | { 20 | // 如果执行程序时输入的参数不正确,给出帮助信息。 21 | if (argc != 2) 22 | { 23 | printf("\nusing:/project/public/demo/demo45 inifile\n"); 24 | printf("samples:/project/public/demo/demo45 /project/public/ini/hssms.xml\n\n"); 25 | return -1; 26 | } 27 | 28 | // 加载参数文件。 29 | CIniFile IniFile; 30 | if (IniFile.LoadFile(argv[1])==false) 31 | { 32 | printf("IniFile.LoadFile(%s) failed.\n",argv[1]); return -1; 33 | } 34 | 35 | // 获取参数,存放在stargs结构中。 36 | memset(&stargs,0,sizeof(struct st_args)); 37 | IniFile.GetValue("logpath",stargs.logpath,300); 38 | IniFile.GetValue("connstr",stargs.connstr,100); 39 | IniFile.GetValue("datapath",stargs.datapath,300); 40 | IniFile.GetValue("serverip",stargs.serverip,50); 41 | IniFile.GetValue("port",&stargs.port); 42 | IniFile.GetValue("online",&stargs.online); 43 | 44 | printf("logpath=%s\n",stargs.logpath); 45 | printf("connstr=%s\n",stargs.connstr); 46 | printf("datapath=%s\n",stargs.datapath); 47 | printf("serverip=%s\n",stargs.serverip); 48 | printf("port=%d\n",stargs.port); 49 | printf("online=%d\n",stargs.online); 50 | 51 | // 以下可以写更多的主程序的代码。 52 | } 53 | 54 | -------------------------------------------------------------------------------- /public/socket/client.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | int main(int argc, char *argv[]) 11 | { 12 | if (argc != 3) 13 | { 14 | printf("usage:./client ip port\n"); return -1; 15 | } 16 | 17 | int sockfd; 18 | struct sockaddr_in servaddr; 19 | char buf[1024]; 20 | 21 | if ((sockfd=socket(AF_INET,SOCK_STREAM,0))<0) { printf("socket() failed.\n"); return -1; } 22 | 23 | memset(&servaddr,0,sizeof(servaddr)); 24 | servaddr.sin_family=AF_INET; 25 | servaddr.sin_port=htons(atoi(argv[2])); 26 | servaddr.sin_addr.s_addr=inet_addr(argv[1]); 27 | 28 | if (connect(sockfd, (struct sockaddr *)&servaddr,sizeof(servaddr)) != 0) 29 | { 30 | printf("connect(%s:%s) failed.\n",argv[1],argv[2]); close(sockfd); return -1; 31 | } 32 | 33 | printf("connect ok.\n"); 34 | 35 | for (int ii=0;ii<5000000000;ii++) 36 | { 37 | // 从命令行输入内容。 38 | memset(buf,0,sizeof(buf)); 39 | printf("please input:"); scanf("%s",buf); 40 | // strcpy(buf,"1111111111111111111111111"); 41 | 42 | if (send(sockfd,buf,strlen(buf),0) <=0) 43 | { 44 | printf("write() failed.\n"); close(sockfd); return -1; 45 | } 46 | 47 | memset(buf,0,sizeof(buf)); 48 | if (recv(sockfd,buf,sizeof(buf),0) <=0) 49 | { 50 | printf("read() failed.\n"); close(sockfd); return -1; 51 | } 52 | 53 | printf("recv:%s\n",buf); 54 | } 55 | } 56 | 57 | -------------------------------------------------------------------------------- /idc/c/idcapp.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************************/ 2 | /* 程序名:idcapp.h,此程序是数据中心项目公用函数和类的声明文件。 */ 3 | /* 作者:吴从周 */ 4 | /****************************************************************************************/ 5 | 6 | #ifndef IDCAPP_H 7 | #define IDCAPP_H 8 | 9 | #include "_public.h" 10 | #include "_mysql.h" 11 | 12 | struct st_zhobtmind 13 | { 14 | char obtid[11]; // 站点代码。 15 | char ddatetime[21]; // 数据时间,精确到分钟。 16 | char t[11]; // 温度,单位:0.1摄氏度。 17 | char p[11]; // 气压,单位:0.1百帕。 18 | char u[11]; // 相对湿度,0-100之间的值。 19 | char wd[11]; // 风向,0-360之间的值。 20 | char wf[11]; // 风速:单位0.1m/s。 21 | char r[11]; // 降雨量:0.1mm。 22 | char vis[11]; // 能见度:0.1米。 23 | }; 24 | 25 | // 全国站点分钟观测数据操作类。 26 | class CZHOBTMIND 27 | { 28 | public: 29 | connection *m_conn; // 数据库连接。 30 | CLogFile *m_logfile; // 日志。 31 | 32 | sqlstatement m_stmt; // 插入表操作的sql。 33 | 34 | char m_buffer[1024]; // 从文件中读到的一行。 35 | struct st_zhobtmind m_zhobtmind; // 全国站点分钟观测数据结构。 36 | 37 | CZHOBTMIND(); 38 | CZHOBTMIND(connection *conn,CLogFile *logfile); 39 | 40 | ~CZHOBTMIND(); 41 | 42 | void BindConnLog(connection *conn,CLogFile *logfile); // 把connection和CLogFile的传进去。 43 | bool SplitBuffer(char *strBuffer,bool bisxml); // 把从文件读到的一行数据拆分到m_zhobtmind结构体中。 44 | bool InsertTable(); // 把m_zhobtmind结构体中的数据插入到T_ZHOBTMIND表中。 45 | }; 46 | 47 | 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /pthread/book15.cpp: -------------------------------------------------------------------------------- 1 | // 本程序演示线程同步-条件变量。 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | pthread_cond_t cond=PTHREAD_COND_INITIALIZER; // 声明条件变量并初始化。 10 | pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER; // 声明互斥锁并初始化。 11 | 12 | void *thmain(void *arg); // 线程主函数。 13 | 14 | void handle(int sig); // 信号15的处理函数。 15 | 16 | int main(int argc,char *argv[]) 17 | { 18 | signal(15,handle); // 设置信号15的处理函数。 19 | 20 | pthread_t thid1,thid2,thid3; 21 | 22 | // 创建线程。 23 | if (pthread_create(&thid1,NULL,thmain,NULL)!=0) { printf("pthread_create failed.\n"); exit(-1); } 24 | if (pthread_create(&thid2,NULL,thmain,NULL)!=0) { printf("pthread_create failed.\n"); exit(-1); } 25 | if (pthread_create(&thid3,NULL,thmain,NULL)!=0) { printf("pthread_create failed.\n"); exit(-1); } 26 | 27 | // 等待子线程退出。 28 | pthread_join(thid1,NULL); pthread_join(thid2,NULL); pthread_join(thid3,NULL); 29 | 30 | pthread_cond_destroy(&cond); // 销毁条件变量。 31 | pthread_mutex_destroy(&mutex); // 销毁互斥锁。 32 | } 33 | 34 | void *thmain(void *arg) // 线程主函数。 35 | { 36 | while (true) 37 | { 38 | printf("线程%lu开始等待条件信号...\n",pthread_self()); 39 | pthread_cond_wait(&cond,&mutex); // 等待条件信号。 40 | printf("线程%lu等待条件信号成功。\n\n",pthread_self()); 41 | } 42 | } 43 | 44 | void handle(int sig) // 信号15的处理函数。 45 | { 46 | printf("发送条件信号...\n"); 47 | // pthread_cond_signal(&cond); // 唤醒等待条件变量的一个线程。 48 | pthread_cond_broadcast(&cond); // 唤醒等待条件变量的全部线程。 49 | } 50 | -------------------------------------------------------------------------------- /public/db/oracle/updatetable.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 程序名:updatetable.cpp,此程序演示开发框架操作Oracle数据库(修改表中的记录)。 3 | * 作者:吴从周。 4 | */ 5 | #include "_ooci.h" // 开发框架操作Oracle的头文件。 6 | 7 | int main(int argc,char *argv[]) 8 | { 9 | connection conn; // 数据库连接类 10 | 11 | // 登录数据库,返回值:0-成功,其它-失败。 12 | // 失败代码在conn.m_cda.rc中,失败描述在conn.m_cda.message中。 13 | if (conn.connecttodb("scott/tiger@snorcl11g_132","Simplified Chinese_China.AL32UTF8")!=0) 14 | { 15 | printf("connect database failed.\n%s\n",conn.m_cda.message); return -1; 16 | } 17 | 18 | sqlstatement stmt(&conn); // 操作SQL语句的对象。 19 | 20 | char strbtime[20]; // 用于存放超女的报名时间。 21 | memset(strbtime,0,sizeof(strbtime)); 22 | strcpy(strbtime,"2019-12-20 09:45:30"); 23 | 24 | // 准备更新数据的SQL语句,不需要判断返回值。 25 | stmt.prepare("\ 26 | update girls set btime=to_date(:1,'yyyy-mm-dd hh24:mi:ss') where id>=2 and id<=4"); 27 | // prepare方法不需要判断返回值。 28 | // 为SQL语句绑定输入变量的地址,bindin方法不需要判断返回值。 29 | stmt.bindin(1,strbtime,19); 30 | // 如果不采用绑定输入变量的方法,把strbtime的值直接写在SQL语句中也是可以的,如下: 31 | /* 32 | stmt.prepare("\ 33 | update girls set btime=to_date('%s','yyyy-mm-dd hh24:mi:ss') where id>=2 and id<=4",strbtime); 34 | */ 35 | 36 | // 执行SQL语句,一定要判断返回值,0-成功,其它-失败。 37 | // 失败代码在stmt.m_cda.rc中,失败描述在stmt.m_cda.message中。 38 | if (stmt.execute() != 0) 39 | { 40 | printf("stmt.execute() failed.\n%s\n%s\n",stmt.m_sql,stmt.m_cda.message); return -1; 41 | } 42 | 43 | // 请注意,stmt.m_cda.rpc变量非常重要,它保存了SQL被执行后影响的记录数。 44 | printf("本次更新了girls表%ld条记录。\n",stmt.m_cda.rpc); 45 | 46 | // 提交事务 47 | conn.commit(); 48 | } 49 | 50 | -------------------------------------------------------------------------------- /idc/sql/T_INTERCFG.sql: -------------------------------------------------------------------------------- 1 | delete from T_INTERCFG; 2 | 3 | /* 获取全部的站点参数。*/ 4 | insert into T_INTERCFG(typeid,intername,intercname,selectsql,colstr,bindin,keyid) 5 | values ('0101','getzhobtcode','全国站点参数','select obtid,cityname,provname,lat,lon,height from T_ZHOBTCODE','obtid,cityname,provname,lat,lon,height',null,SEQ_INTERCFG.nextval); 6 | 7 | /* 按站点获取全国站点分钟观测数据。 */ 8 | insert into T_INTERCFG(typeid,intername,intercname,selectsql,colstr,bindin,keyid) 9 | values ('0102','getzhobtmind1','全国站点分钟观测数据(按站点)','select obtid,to_char(ddatetime,''yyyymmddhh24miss''),t,p,u,wd,wf,r,vis from T_ZHOBTMIND where obtid=:1','obtid,ddatetime,t,p,u,wd,wf,r,vis','obtid',SEQ_INTERCFG.nextval); 10 | 11 | /* 按时间段获取全国站点分钟观测数据。 */ 12 | insert into T_INTERCFG(typeid,intername,intercname,selectsql,colstr,bindin,keyid) 13 | values ('0102','getzhobtmind2','全国站点分钟观测数据(按时间段)','select obtid,to_char(ddatetime,''yyyymmddhh24miss''),t,p,u,wd,wf,r,vis from T_ZHOBTMIND where ddatetime>=to_date(:1,''yyyymmddhh24miss'') and ddatetime<=to_date(:2,''yyyymmddhh24miss'')','obtid,ddatetime,t,p,u,wd,wf,r,vis','begintime,endtime',SEQ_INTERCFG.nextval); 14 | 15 | /* 按站点和时间段获取全国站点分钟观测数据。 */ 16 | insert into T_INTERCFG(typeid,intername,intercname,selectsql,colstr,bindin,keyid) 17 | values ('0102','getzhobtmind3','全国站点分钟观测数据(按站点和时间段)','select obtid,to_char(ddatetime,''yyyymmddhh24miss''),t,p,u,wd,wf,r,vis from T_ZHOBTMIND where obtid=:1 and ddatetime>=to_date(:2,''yyyymmddhh24miss'') and ddatetime<=to_date(:3,''yyyymmddhh24miss'')','obtid,ddatetime,t,p,u,wd,wf,r,vis','obtid,begintime,endtime',SEQ_INTERCFG.nextval); 18 | 19 | exit; 20 | 21 | -------------------------------------------------------------------------------- /public/db/mysql/makefile: -------------------------------------------------------------------------------- 1 | # mysql头文件存放的目录。 2 | MYSQLINCL = -I/usr/local/mysql/include 3 | 4 | # mysql库文件存放的目录。 5 | MYSQLLIB = -L/usr/local/mysql/lib 6 | 7 | # 需要链接的mysql库。 8 | MYSQLLIBS = -lmysqlclient 9 | 10 | CFLAGS=-g -Wno-write-strings 11 | 12 | all:createtable inserttable updatetable selecttable deletetable filetoblob blobtofile 13 | 14 | createtable:createtable.cpp _mysql.h _mysql.cpp 15 | g++ $(CFLAGS) -o createtable createtable.cpp $(MYSQLINCL) $(MYSQLLIB) $(MYSQLLIBS) _mysql.cpp -lm -lc 16 | 17 | inserttable:inserttable.cpp _mysql.h _mysql.cpp 18 | g++ $(CFLAGS) -o inserttable inserttable.cpp $(MYSQLINCL) $(MYSQLLIB) $(MYSQLLIBS) _mysql.cpp -lm -lc 19 | 20 | updatetable:updatetable.cpp _mysql.h _mysql.cpp 21 | g++ $(CFLAGS) -o updatetable updatetable.cpp $(MYSQLINCL) $(MYSQLLIB) $(MYSQLLIBS) _mysql.cpp -lm -lc 22 | 23 | selecttable:selecttable.cpp _mysql.h _mysql.cpp 24 | g++ $(CFLAGS) -o selecttable selecttable.cpp $(MYSQLINCL) $(MYSQLLIB) $(MYSQLLIBS) _mysql.cpp -lm -lc 25 | 26 | deletetable:deletetable.cpp _mysql.h _mysql.cpp 27 | g++ $(CFLAGS) -o deletetable deletetable.cpp $(MYSQLINCL) $(MYSQLLIB) $(MYSQLLIBS) _mysql.cpp -lm -lc 28 | 29 | filetoblob:filetoblob.cpp _mysql.h _mysql.cpp 30 | g++ $(CFLAGS) -o filetoblob filetoblob.cpp $(MYSQLINCL) $(MYSQLLIB) $(MYSQLLIBS) _mysql.cpp -lm -lc 31 | 32 | blobtofile:blobtofile.cpp _mysql.h _mysql.cpp 33 | g++ $(CFLAGS) -o blobtofile blobtofile.cpp $(MYSQLINCL) $(MYSQLLIB) $(MYSQLLIBS) _mysql.cpp -lm -lc 34 | 35 | clean: 36 | rm -rf createtable inserttable updatetable selecttable deletetable filetoblob blobtofile 37 | -------------------------------------------------------------------------------- /public/db/postgresql/makefile: -------------------------------------------------------------------------------- 1 | ######################################### 2 | 3 | # postgresql头文件存放路径 4 | PGINCL = -I/usr/include 5 | 6 | # postgresql库文件保存路径 7 | PGLIB = -L/usr/lib64 8 | 9 | # postgresql链接库 10 | PGLIBS = -lpq 11 | 12 | 13 | #CFLAGS = -O2 14 | CFLAGS = -O2 -Wall 15 | 16 | #CFLAGS = -g -Wall 17 | CFLAGS = -g -Wno-write-strings 18 | 19 | 20 | all: createtable inserttable selecttable counttable updatetable deletetable 21 | 22 | createtable: createtable.cpp _postgresql.h _postgresql.cpp 23 | g++ $(CFLAGS) -o createtable createtable.cpp _postgresql.cpp $(PGINCL) $(PGLIB) $(PGLIBS) -lm -lc 24 | 25 | inserttable: inserttable.cpp _postgresql.h _postgresql.cpp 26 | g++ $(CFLAGS) -o inserttable inserttable.cpp _postgresql.cpp $(PGINCL) $(PGLIB) $(PGLIBS) -lm -lc 27 | 28 | selecttable: selecttable.cpp _postgresql.h _postgresql.cpp 29 | g++ $(CFLAGS) -o selecttable selecttable.cpp _postgresql.cpp $(PGINCL) $(PGLIB) $(PGLIBS) -lm -lc 30 | 31 | counttable: counttable.cpp _postgresql.h _postgresql.cpp 32 | g++ $(CFLAGS) -o counttable counttable.cpp _postgresql.cpp $(PGINCL) $(PGLIB) $(PGLIBS) -lm -lc 33 | 34 | updatetable: updatetable.cpp _postgresql.h _postgresql.cpp 35 | g++ $(CFLAGS) -o updatetable updatetable.cpp _postgresql.cpp $(PGINCL) $(PGLIB) $(PGLIBS) -lm -lc 36 | 37 | deletetable: deletetable.cpp _postgresql.h _postgresql.cpp 38 | g++ $(CFLAGS) -o deletetable deletetable.cpp _postgresql.cpp $(PGINCL) $(PGLIB) $(PGLIBS) -lm -lc 39 | 40 | clean: 41 | rm -rf createtable inserttable selecttable counttable updatetable deletetable 42 | -------------------------------------------------------------------------------- /public/db/oracle/execplsql.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 程序名:execplsql.cpp,此程序演示开发框架操作Oracle数据库(执行PL/SQL过程)。 3 | * 作者:吴从周。 4 | * 说说我个人的看法,我从不在Oracle数据库中创建PL/SQL过程,也很少使用触发器,原因如下: 5 | * 1、在Oracle数据库中创建PL/SQL过程,程序的调试很麻烦; 6 | * 2、维护工作很麻烦,因为维护人员要花时间去了解数据库中的存储过程; 7 | * 3、采用本开发框架操作Oracle已经是非常简单,没必要去折腾存储过程; 8 | * 4、PL/SQL过程可移植性不好,如果换成mysql或其它数据库,比较麻烦。 9 | * 还有,我在C/C++程序中很少用复杂的PL/SQL过程,因为复杂的PL/SQL调试麻烦。 10 | */ 11 | #include "_ooci.h" // 开发框架操作Oracle的头文件。 12 | 13 | int main(int argc,char *argv[]) 14 | { 15 | connection conn; // 数据库连接类 16 | 17 | // 登录数据库,返回值:0-成功,其它-失败。 18 | // 失败代码在conn.m_cda.rc中,失败描述在conn.m_cda.message中。 19 | if (conn.connecttodb("scott/tiger@snorcl11g_132","Simplified Chinese_China.AL32UTF8")!=0) 20 | { 21 | printf("connect database failed.\n%s\n",conn.m_cda.message); return -1; 22 | } 23 | 24 | sqlstatement stmt(&conn); // 操作SQL语句的对象。 25 | 26 | int id=100; 27 | 28 | // 准备查询表的PL/SQL语句,先删除girls表中的全部记录,再插入一条记录。 29 | stmt.prepare("\ 30 | BEGIN\ 31 | delete from girls;\ 32 | insert into girls(id,name,weight,btime)\ 33 | values(:1,'超女过程',55.65,to_date('2018-01-02 13:00:55','yyyy-mm-dd hh24:mi:ss'));\ 34 | END;"); 35 | // 注意,PL/SQL中的每条SQL需要用分号结束,END之后还有一个分号。 36 | // prepare方法不需要判断返回值。 37 | // 为PL/SQL语句绑定输入变量的地址,bindin方法不需要判断返回值。 38 | stmt.bindin(1,&id); 39 | 40 | // 执行SQL语句,一定要判断返回值,0-成功,其它-失败。 41 | if (stmt.execute() != 0) 42 | { 43 | printf("stmt.execute() failed.\n%s\n%s\n",stmt.m_sql,stmt.m_cda.message); return -1; 44 | } 45 | 46 | printf("exec PL/SQL ok.\n"); 47 | 48 | // 提交事务。 49 | conn.commit(); 50 | } 51 | 52 | -------------------------------------------------------------------------------- /public/db/postgresql/updatetable.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 程序名:updatetable.cpp,此程序演示开发框架操作PostgreSQL数据库(修改表中的记录)。 3 | * 作者:吴从周。 4 | */ 5 | #include "_postgresql.h" // 开发框架操作PostgreSQL的头文件。 6 | 7 | int main(int argc,char *argv[]) 8 | { 9 | connection conn; // 数据库连接类 10 | 11 | // 登录数据库,返回值:0-成功,其它-失败。 12 | // 失败代码在conn.m_cda.rc中,失败描述在conn.m_cda.message中。 13 | if (conn.connecttodb("host=172.16.0.15 user=postgres password=pwdidc dbname=postgres port=5432","gbk")!=0) 14 | { 15 | printf("connect database failed.\n%s\n",conn.m_cda.message); return -1; 16 | } 17 | 18 | sqlstatement stmt(&conn); // 操作SQL语句的对象。 19 | 20 | char strbtime[20]; // 用于存放超女的报名时间。 21 | memset(strbtime,0,sizeof(strbtime)); 22 | strcpy(strbtime,"2019-12-20 09:45:30"); 23 | 24 | // 准备更新数据的SQL语句,不需要判断返回值。 25 | stmt.prepare("\ 26 | update girls set btime=to_date(:1,'yyyy-mm-dd hh24:mi:ss') where id>=2 and id<=4"); 27 | // prepare方法不需要判断返回值。 28 | // 为SQL语句绑定输入变量的地址,bindin方法不需要判断返回值。 29 | stmt.bindin(1,strbtime,19); 30 | // 如果不采用绑定输入变量的方法,把strbtime的值直接写在SQL语句中也是可以的,如下: 31 | /* 32 | stmt.prepare("\ 33 | update girls set btime=to_date('%s','yyyy-mm-dd hh24:mi:ss') where id>=2 and id<=4",strbtime); 34 | */ 35 | 36 | // 执行SQL语句,一定要判断返回值,0-成功,其它-失败。 37 | // 失败代码在stmt.m_cda.rc中,失败描述在stmt.m_cda.message中。 38 | if (stmt.execute() != 0) 39 | { 40 | printf("stmt.execute() failed.\n%s\n%s\n",stmt.m_sql,stmt.m_cda.message); return -1; 41 | } 42 | 43 | // 请注意,stmt.m_cda.rpc变量非常重要,它保存了SQL被执行后影响的记录数。 44 | printf("本次更新了girls表%ld条记录。\n",stmt.m_cda.rpc); 45 | 46 | // 提交事务 47 | conn.commit(); 48 | } 49 | 50 | -------------------------------------------------------------------------------- /public/socket/demo03.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 程序名:demo03.cpp,此程序用于演示粘包的socket客户端。 3 | * 作者:吴从周。 4 | */ 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | int main(int argc,char *argv[]) 15 | { 16 | if (argc!=3) 17 | { 18 | printf("Using:./demo03 ip port\nExample:./demo03 127.0.0.1 5005\n\n"); return -1; 19 | } 20 | 21 | // 第1步:创建客户端的socket。 22 | int sockfd; 23 | if ( (sockfd = socket(AF_INET,SOCK_STREAM,0))==-1) { perror("socket"); return -1; } 24 | 25 | // 第2步:向服务器发起连接请求。 26 | struct hostent* h; 27 | if ( (h = gethostbyname(argv[1])) == 0 ) // 指定服务端的ip地址。 28 | { printf("gethostbyname failed.\n"); close(sockfd); return -1; } 29 | struct sockaddr_in servaddr; 30 | memset(&servaddr,0,sizeof(servaddr)); 31 | servaddr.sin_family = AF_INET; 32 | servaddr.sin_port = htons(atoi(argv[2])); // 指定服务端的通讯端口。 33 | memcpy(&servaddr.sin_addr,h->h_addr,h->h_length); 34 | if (connect(sockfd, (struct sockaddr *)&servaddr,sizeof(servaddr)) != 0) // 向服务端发起连接清求。 35 | { perror("connect"); close(sockfd); return -1; } 36 | 37 | int iret; 38 | char buffer[1024]; 39 | 40 | // 第3步:与服务端通讯,连续发送1000个报文。 41 | for (int ii=0;ii<1000;ii++) 42 | { 43 | memset(buffer,0,sizeof(buffer)); 44 | sprintf(buffer,"这是第%d个超级女生,编号%03d。",ii+1,ii+1); 45 | 46 | if ( (iret=send(sockfd,buffer,strlen(buffer),0))<=0) // 向服务端发送请求报文。 47 | { perror("send"); break; } 48 | 49 | printf("发送:%s\n",buffer); 50 | } 51 | 52 | // 第4步:关闭socket,释放资源。 53 | close(sockfd); 54 | } 55 | 56 | -------------------------------------------------------------------------------- /pthread/book8.cpp: -------------------------------------------------------------------------------- 1 | // 本程序演示线程资源的回收(线程清理函数)。 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | void *thmain(void *arg); // 线程主函数。 9 | 10 | void thcleanup1(void *arg); // 线程清理函数1。 11 | void thcleanup2(void *arg); // 线程清理函数2。 12 | void thcleanup3(void *arg); // 线程清理函数3。 13 | 14 | int main(int argc,char *argv[]) 15 | { 16 | pthread_t thid; 17 | 18 | // 创建线程。 19 | if (pthread_create(&thid,NULL,thmain,NULL)!=0) { printf("pthread_create failed.\n"); exit(-1); } 20 | 21 | int result=0; 22 | void *ret; 23 | printf("join...\n"); 24 | result=pthread_join(thid,&ret); printf("thid result=%d,ret=%ld\n",result,ret); 25 | printf("join ok.\n"); 26 | } 27 | 28 | void *thmain(void *arg) // 线程主函数。 29 | { 30 | pthread_cleanup_push(thcleanup1,NULL); // 把线程清理函数1入栈(关闭文件指针)。 31 | pthread_cleanup_push(thcleanup2,NULL); // 把线程清理函数2入栈(关闭socket)。 32 | pthread_cleanup_push(thcleanup3,NULL); // 把线程清理函数3入栈(回滚数据库事务)。 33 | 34 | for (int ii=0;ii<3;ii++) 35 | { 36 | sleep(1); printf("pthmain sleep(%d) ok.\n",ii+1); 37 | } 38 | 39 | pthread_cleanup_pop(3); // 把线程清理函数3出栈。 40 | pthread_cleanup_pop(2); // 把线程清理函数2出栈。 41 | pthread_cleanup_pop(1); // 把线程清理函数1出栈。 42 | } 43 | 44 | void thcleanup1(void *arg) 45 | { 46 | // 在这里释放关闭文件、断开网络连接、回滚数据库事务、释放锁等等。 47 | printf("cleanup1 ok.\n"); 48 | }; 49 | 50 | void thcleanup2(void *arg) 51 | { 52 | // 在这里释放关闭文件、断开网络连接、回滚数据库事务、释放锁等等。 53 | printf("cleanup2 ok.\n"); 54 | }; 55 | 56 | void thcleanup3(void *arg) 57 | { 58 | // 在这里释放关闭文件、断开网络连接、回滚数据库事务、释放锁等等。 59 | printf("cleanup3 ok.\n"); 60 | }; 61 | 62 | -------------------------------------------------------------------------------- /pthread/makefile: -------------------------------------------------------------------------------- 1 | all: book1 book2 book3 book4 book5 book6 book7 book8 book9 book10 book11\ 2 | book12 book13 book14 book15 book16 book17 book18 book19 3 | 4 | book1:book1.cpp 5 | g++ -g -o book1 book1.cpp -lpthread 6 | 7 | book2:book2.cpp 8 | g++ -g -o book2 book2.cpp -lpthread 9 | 10 | book3:book3.cpp 11 | g++ -g -o book3 book3.cpp -lpthread 12 | 13 | book4:book4.cpp 14 | g++ -g -o book4 book4.cpp -lpthread 15 | 16 | book5:book5.cpp 17 | g++ -g -o book5 book5.cpp -lpthread 18 | 19 | book6:book6.cpp 20 | g++ -g -o book6 book6.cpp -lpthread 21 | 22 | book7:book7.cpp 23 | g++ -g -o book7 book7.cpp -lpthread 24 | 25 | book8:book8.cpp 26 | g++ -g -o book8 book8.cpp -lpthread 27 | 28 | book9:book9.cpp 29 | g++ -g -o book9 book9.cpp -lpthread 30 | 31 | book10:book10.cpp 32 | g++ -g -o book10 book10.cpp -lpthread 33 | 34 | book11:book11.cpp 35 | g++ -g -o book11 book11.cpp -lpthread -std=c++11 36 | 37 | book12:book12.cpp 38 | g++ -g -o book12 book12.cpp -lpthread 39 | 40 | book13:book13.cpp 41 | g++ -g -o book13 book13.cpp -lpthread 42 | 43 | book14:book14.cpp 44 | g++ -g -o book14 book14.cpp -lpthread 45 | 46 | book15:book15.cpp 47 | g++ -g -o book15 book15.cpp -lpthread 48 | 49 | book16:book16.cpp 50 | g++ -g -o book16 book16.cpp -lpthread 51 | 52 | book17:book17.cpp 53 | g++ -g -o book17 book17.cpp -lpthread 54 | 55 | book18:book18.cpp 56 | g++ -g -o book18 book18.cpp -lpthread 57 | 58 | book19:book19.cpp 59 | g++ -g -o book19 book19.cpp -lpthread 60 | 61 | clean: 62 | rm book1 book2 book3 book4 book5 book6 book7 book8 book9 book10 book11 63 | rm book12 book13 book14 book15 book16 book17 book18 book19 64 | -------------------------------------------------------------------------------- /pthread/book14.cpp: -------------------------------------------------------------------------------- 1 | // 本程序演示线程同步-读写锁。 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | pthread_rwlock_t rwlock=PTHREAD_RWLOCK_INITIALIZER; // 声明读写锁并初始化。 10 | 11 | void *thmain(void *arg); // 线程主函数。 12 | 13 | void handle(int sig); // 信号15的处理函数。 14 | 15 | int main(int argc,char *argv[]) 16 | { 17 | signal(15,handle); // 设置信号15的处理函数。 18 | 19 | pthread_t thid1,thid2,thid3; 20 | 21 | // 创建线程。 22 | if (pthread_create(&thid1,NULL,thmain,NULL)!=0) { printf("pthread_create failed.\n"); exit(-1); } 23 | sleep(1); 24 | if (pthread_create(&thid2,NULL,thmain,NULL)!=0) { printf("pthread_create failed.\n"); exit(-1); } 25 | sleep(1); 26 | if (pthread_create(&thid3,NULL,thmain,NULL)!=0) { printf("pthread_create failed.\n"); exit(-1); } 27 | 28 | // 等待子线程退出。 29 | pthread_join(thid1,NULL); pthread_join(thid2,NULL); pthread_join(thid3,NULL); 30 | 31 | pthread_rwlock_destroy(&rwlock); // 销毁锁。 32 | } 33 | 34 | void *thmain(void *arg) // 线程主函数。 35 | { 36 | for (int ii=0;ii<100;ii++) 37 | { 38 | printf("线程%lu开始申请读锁...\n",pthread_self()); 39 | pthread_rwlock_rdlock(&rwlock); // 加锁。 40 | printf("线程%lu开始申请读锁成功。\n\n",pthread_self()); 41 | sleep(5); 42 | pthread_rwlock_unlock(&rwlock); // 解锁。 43 | printf("线程%lu已释放读锁。\n\n",pthread_self()); 44 | 45 | if (ii==3) sleep(8); 46 | } 47 | } 48 | 49 | void handle(int sig) // 信号15的处理函数。 50 | { 51 | printf("开始申请写锁...\n"); 52 | pthread_rwlock_wrlock(&rwlock); // 加锁。 53 | printf("申请写锁成功。\n\n"); 54 | sleep(10); 55 | pthread_rwlock_unlock(&rwlock); // 解锁。 56 | printf("写锁已释放。\n\n"); 57 | } 58 | -------------------------------------------------------------------------------- /public/socket/demo06.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 程序名:demo06.cpp,此程序用于演示不粘包的socket服务端。 3 | * 作者:吴从周 4 | */ 5 | #include "../_public.h" 6 | 7 | int main(int argc,char *argv[]) 8 | { 9 | if (argc!=2) 10 | { 11 | printf("Using:./demo06 port\nExample:./demo06 5005\n\n"); return -1; 12 | } 13 | 14 | // 第1步:创建服务端的socket。 15 | int listenfd; 16 | if ( (listenfd = socket(AF_INET,SOCK_STREAM,0))==-1) { perror("socket"); return -1; } 17 | 18 | // 第2步:把服务端用于通讯的地址和端口绑定到socket上。 19 | struct sockaddr_in servaddr; // 服务端地址信息的数据结构。 20 | memset(&servaddr,0,sizeof(servaddr)); 21 | servaddr.sin_family = AF_INET; // 协议族,在socket编程中只能是AF_INET。 22 | servaddr.sin_addr.s_addr = htonl(INADDR_ANY); // 任意ip地址。 23 | servaddr.sin_port = htons(atoi(argv[1])); // 指定通讯端口。 24 | if (bind(listenfd,(struct sockaddr *)&servaddr,sizeof(servaddr)) != 0 ) 25 | { perror("bind"); close(listenfd); return -1; } 26 | 27 | // 第3步:把socket设置为监听模式。 28 | if (listen(listenfd,5) != 0 ) { perror("listen"); close(listenfd); return -1; } 29 | 30 | // 第4步:接受客户端的连接。 31 | int clientfd; // 客户端的socket。 32 | int socklen=sizeof(struct sockaddr_in); // struct sockaddr_in的大小 33 | struct sockaddr_in clientaddr; // 客户端的地址信息。 34 | clientfd=accept(listenfd,(struct sockaddr *)&clientaddr,(socklen_t*)&socklen); 35 | printf("客户端(%s)已连接。\n",inet_ntoa(clientaddr.sin_addr)); 36 | 37 | char buffer[1024]; 38 | 39 | // 第5步:与客户端通讯,接收客户端发过来的报文。 40 | while (1) 41 | { 42 | memset(buffer,0,sizeof(buffer)); 43 | 44 | int ibuflen=0; 45 | if (TcpRead(clientfd,buffer,&ibuflen)==false) break; // 接收客户端的请求报文。 46 | 47 | printf("接收:%s\n",buffer); 48 | } 49 | 50 | // 第6步:关闭socket,释放资源。 51 | close(listenfd); close(clientfd); 52 | } 53 | -------------------------------------------------------------------------------- /public/db/oracle/filetoclob.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 程序名:filetoclob.cpp,此程序演示开发框架操作Oracle数据库。 3 | * 把当前目录中的memo_in.txt文件写入Oracle的CLOB字段中。 4 | * 作者:吴从周。 5 | */ 6 | #include "_ooci.h" // 开发框架操作Oracle的头文件。 7 | 8 | int main(int argc,char *argv[]) 9 | { 10 | connection conn; // 数据库连接类 11 | 12 | // 连接数据库,返回值0-成功,其它-失败 13 | // 失败代码在conn.m_cda.rc中,失败描述在conn.m_cda.message中。 14 | if (conn.connecttodb("scott/tiger@snorcl11g_132","Simplified Chinese_China.AL32UTF8") != 0) 15 | { 16 | printf("connect database failed.\n%s\n",conn.m_cda.message); return -1; 17 | } 18 | 19 | sqlstatement stmt(&conn); // SQL语句操作类 20 | 21 | // 为了方便演示,把girls表中的记录全删掉,再插入一条用于测试的数据。 22 | // 不需要判断返回值 23 | stmt.prepare("\ 24 | BEGIN\ 25 | delete from girls;\ 26 | insert into girls(id,name,memo) values(1,'超女姓名',empty_clob());\ 27 | END;"); 28 | 29 | // 执行SQL语句,一定要判断返回值,0-成功,其它-失败。 30 | if (stmt.execute() != 0) 31 | { 32 | printf("stmt.execute() failed.\n%s\n%s\n",stmt.m_sql,stmt.m_cda.message); return -1; 33 | } 34 | 35 | // 使用游标从girls表中提取id为1的memo字段 36 | // 注意了,同一个sqlstatement可以多次使用 37 | // 但是,如果它的sql改变了,就要重新prepare和bindin或bindout变量 38 | stmt.prepare("select memo from girls where id=1 for update"); 39 | stmt.bindclob(); 40 | 41 | // 执行SQL语句,一定要判断返回值,0-成功,其它-失败。 42 | if (stmt.execute() != 0) 43 | { 44 | printf("stmt.execute() failed.\n%s\n%s\n",stmt.m_sql,stmt.m_cda.message); return -1; 45 | } 46 | 47 | // 获取一条记录,一定要判断返回值,0-成功,1403-无记录,其它-失败。 48 | if (stmt.next() != 0) return 0; 49 | 50 | // 把磁盘文件memo_in.txt的内容写入CLOB字段 51 | if (stmt.filetolob((char *)"memo_in.txt") != 0) 52 | { 53 | printf("stmt.filetolob() failed.\n%s\n",stmt.m_cda.message); return -1; 54 | } 55 | 56 | conn.commit(); // 提交事务 57 | } 58 | 59 | -------------------------------------------------------------------------------- /public/db/oracle/filetoblob.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 程序名:filetoblob.cpp,此程序演示开发框架操作Oracle数据库。 3 | * 把当前目录的pic_in.jpeg文件写入Oracle的BLOB字段中。 4 | * 作者:吴从周。 5 | */ 6 | #include "_ooci.h" // 开发框架操作Oracle的头文件。 7 | 8 | int main(int argc,char *argv[]) 9 | { 10 | connection conn; // 数据库连接类 11 | 12 | // 连接数据库,返回值0-成功,其它-失败 13 | // 失败代码在conn.m_cda.rc中,失败描述在conn.m_cda.message中。 14 | if (conn.connecttodb("scott/tiger@snorcl11g_132","Simplified Chinese_China.AL32UTF8") != 0) 15 | { 16 | printf("connect database failed.\n%s\n",conn.m_cda.message); return -1; 17 | } 18 | 19 | sqlstatement stmt(&conn); // SQL语句操作类 20 | 21 | // 为了方便演示,把girls表中的记录全删掉,再插入一条用于测试的数据。 22 | // 不需要判断返回值 23 | stmt.prepare("\ 24 | BEGIN\ 25 | delete from girls;\ 26 | insert into girls(id,name,pic) values(1,'超女姓名',empty_blob());\ 27 | END;"); 28 | 29 | // 执行SQL语句,一定要判断返回值,0-成功,其它-失败。 30 | if (stmt.execute() != 0) 31 | { 32 | printf("stmt.execute() failed.\n%s\n%s\n",stmt.m_sql,stmt.m_cda.message); return -1; 33 | } 34 | 35 | // 使用游标从girls表中提取id为1的pic字段 36 | // 注意了,同一个sqlstatement可以多次使用 37 | // 但是,如果它的sql改变了,就要重新prepare和bindin或bindout变量 38 | stmt.prepare("select pic from girls where id=1 for update"); 39 | stmt.bindblob(); 40 | 41 | // 执行SQL语句,一定要判断返回值,0-成功,其它-失败。 42 | if (stmt.execute() != 0) 43 | { 44 | printf("stmt.execute() failed.\n%s\n%s\n",stmt.m_sql,stmt.m_cda.message); return -1; 45 | } 46 | 47 | // 获取一条记录,一定要判断返回值,0-成功,1403-无记录,其它-失败。 48 | if (stmt.next() != 0) return 0; 49 | 50 | // 把磁盘文件pic_in.jpeg的内容写入BLOB字段,一定要判断返回值,0-成功,其它-失败。 51 | if (stmt.filetolob((char *)"pic_in.jpeg") != 0) 52 | { 53 | printf("stmt.filetolob() failed.\n%s\n",stmt.m_cda.message); return -1; 54 | } 55 | 56 | conn.commit(); // 提交事 57 | } 58 | 59 | -------------------------------------------------------------------------------- /pthread/book17.cpp: -------------------------------------------------------------------------------- 1 | // 本程序演示线程同步-条件变量,pthread_cond_wait(&cond,&mutex)函数中发生了什么? 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | pthread_cond_t cond=PTHREAD_COND_INITIALIZER; // 声明条件变量并初始化。 10 | pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER; // 声明互斥锁并初始化。 11 | 12 | void *thmain1(void *arg); // 线程1主函数。 13 | void *thmain2(void *arg); // 线程2主函数。 14 | 15 | int main(int argc,char *argv[]) 16 | { 17 | pthread_t thid1,thid2; 18 | 19 | // 创建线程。 20 | if (pthread_create(&thid1,NULL,thmain1,NULL)!=0) { printf("pthread_create failed.\n"); exit(-1); } 21 | sleep(1); 22 | if (pthread_create(&thid2,NULL,thmain2,NULL)!=0) { printf("pthread_create failed.\n"); exit(-1); } 23 | 24 | // 等待子线程退出。 25 | pthread_join(thid1,NULL); pthread_join(thid2,NULL); 26 | 27 | pthread_cond_destroy(&cond); // 销毁条件变量。 28 | pthread_mutex_destroy(&mutex); // 销毁互斥锁。 29 | } 30 | 31 | void *thmain1(void *arg) // 线程1的主函数。 32 | { 33 | printf("线程一申请互斥锁...\n"); 34 | pthread_mutex_lock(&mutex); 35 | printf("线程一申请互斥锁成功。\n"); 36 | 37 | printf("线程一开始等待条件信号...\n"); 38 | pthread_cond_wait(&cond,&mutex); // 等待条件信号。 39 | printf("线程一等待条件信号成功。\n"); 40 | } 41 | 42 | void *thmain2(void *arg) // 线程2的主函数。 43 | { 44 | printf("线程二申请互斥锁...\n"); 45 | pthread_mutex_lock(&mutex); 46 | printf("线程二申请互斥锁成功。\n"); 47 | 48 | pthread_cond_signal(&cond); 49 | 50 | sleep(5); 51 | 52 | printf("线程二解锁。\n"); 53 | pthread_mutex_unlock(&mutex); 54 | 55 | return 0; 56 | 57 | printf("线程二申请互斥锁...\n"); 58 | pthread_mutex_lock(&mutex); 59 | printf("线程二申请互斥锁成功。\n"); 60 | 61 | printf("线程二开始等待条件信号...\n"); 62 | pthread_cond_wait(&cond,&mutex); // 等待条件信号。 63 | printf("线程二等待条件信号成功。\n"); 64 | } 65 | 66 | -------------------------------------------------------------------------------- /public/db/mysql/filetoblob.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 程序名:filetoblob.cpp,此程序演示开发框架操作MySQL数据库(把图片文件存入BLOB字段)。 3 | * 作者:吴从周。 4 | */ 5 | 6 | #include "_mysql.h" // 开发框架操作MySQL的头文件。 7 | 8 | int main(int argc,char *argv[]) 9 | { 10 | connection conn; // 数据库连接类。 11 | 12 | // 登录数据库,返回值:0-成功;其它是失败,存放了MySQL的错误代码。 13 | // 失败代码在conn.m_cda.rc中,失败描述在conn.m_cda.message中。 14 | if (conn.connecttodb("127.0.0.1,root,mysqlpwd,mysql,3306","utf8")!=0) 15 | { 16 | printf("connect database failed.\n%s\n",conn.m_cda.message); return -1; 17 | } 18 | 19 | // 定义用于超女信息的结构,与表中的字段对应。 20 | struct st_girls 21 | { 22 | long id; // 超女编号 23 | char pic[100000]; // 超女图片的内容。 24 | unsigned long picsize; // 图片内容占用的字节数。 25 | } stgirls; 26 | 27 | sqlstatement stmt(&conn); // 操作SQL语句的对象。 28 | 29 | // 准备修改表的SQL语句。 30 | stmt.prepare("update girls set pic=:1 where id=:2"); 31 | stmt.bindinlob(1, stgirls.pic,&stgirls.picsize); 32 | stmt.bindin(2,&stgirls.id); 33 | 34 | // 修改超女信息表中id为1、2的记录。 35 | for (int ii=1;ii<3;ii++) 36 | { 37 | memset(&stgirls,0,sizeof(struct st_girls)); // 结构体变量初始化。 38 | 39 | // 为结构体变量的成员赋值。 40 | stgirls.id=ii; // 超女编号。 41 | // 把图片的内容加载到stgirls.pic中。 42 | if (ii==1) stgirls.picsize=filetobuf("1.jpg",stgirls.pic); 43 | if (ii==2) stgirls.picsize=filetobuf("2.jpg",stgirls.pic); 44 | 45 | // 执行SQL语句,一定要判断返回值,0-成功,其它-失败。 46 | // 失败代码在stmt.m_cda.rc中,失败描述在stmt.m_cda.message中。 47 | if (stmt.execute()!=0) 48 | { 49 | printf("stmt.execute() failed.\n%s\n%s\n",stmt.m_sql,stmt.m_cda.message); return -1; 50 | } 51 | 52 | printf("成功修改了%ld条记录。\n",stmt.m_cda.rpc); // stmt.m_cda.rpc是本次执行SQL影响的记录数。 53 | } 54 | 55 | printf("update table girls ok.\n"); 56 | 57 | conn.commit(); // 提交数据库事务。 58 | 59 | return 0; 60 | } 61 | 62 | -------------------------------------------------------------------------------- /public/db/mysql/blobtofile.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 程序名:blobtofile.cpp,此程序演示开发框架操作MySQL数据库(提取BLOB字段内容到图片文件中)。 3 | * 作者:吴从周。 4 | */ 5 | 6 | #include "_mysql.h" // 开发框架操作MySQL的头文件。 7 | 8 | int main(int argc,char *argv[]) 9 | { 10 | connection conn; // 数据库连接类。 11 | 12 | // 登录数据库,返回值:0-成功;其它是失败,存放了MySQL的错误代码。 13 | // 失败代码在conn.m_cda.rc中,失败描述在conn.m_cda.message中。 14 | if (conn.connecttodb("127.0.0.1,root,mysqlpwd,mysql,3306","utf8")!=0) 15 | { 16 | printf("connect database failed.\n%s\n",conn.m_cda.message); return -1; 17 | } 18 | 19 | // 定义用于超女信息的结构,与表中的字段对应。 20 | struct st_girls 21 | { 22 | long id; // 超女编号 23 | char pic[100000]; // 超女图片的内容。 24 | unsigned long picsize; // 图片内容占用的字节数。 25 | } stgirls; 26 | 27 | sqlstatement stmt(&conn); // 操作SQL语句的对象。 28 | 29 | // 准备查询表的SQL语句。 30 | stmt.prepare("select id,pic from girls where id in (1,2)"); 31 | stmt.bindout(1,&stgirls.id); 32 | stmt.bindoutlob(2, stgirls.pic,100000,&stgirls.picsize); 33 | 34 | // 执行SQL语句,一定要判断返回值,0-成功,其它-失败。 35 | // 失败代码在stmt.m_cda.rc中,失败描述在stmt.m_cda.message中。 36 | if (stmt.execute()!=0) 37 | { 38 | printf("stmt.execute() failed.\n%s\n%s\n",stmt.m_sql,stmt.m_cda.message); return -1; 39 | } 40 | 41 | // 本程序执行的是查询语句,执行stmt.execute()后,将会在数据库的缓冲区中产生一个结果集。 42 | while (true) 43 | { 44 | memset(&stgirls,0,sizeof(stgirls)); // 先把结构体变量初始化。 45 | 46 | // 从结果集中获取一条记录,一定要判断返回值,0-成功,1403-无记录,其它-失败。 47 | // 在实际开发中,除了0和1403,其它的情况极少出现。 48 | if (stmt.next()!=0) break; 49 | 50 | // 生成文件名。 51 | char filename[101]; memset(filename,0,sizeof(filename)); 52 | sprintf(filename,"%d_out.jpg",stgirls.id); 53 | 54 | // 把内容写入文件。 55 | buftofile(filename,stgirls.pic,stgirls.picsize); 56 | } 57 | 58 | // 请注意,stmt.m_cda.rpc变量非常重要,它保存了SQL被执行后影响的记录数。 59 | printf("本次查询了girls表%ld条记录。\n",stmt.m_cda.rpc); 60 | 61 | return 0; 62 | } 63 | 64 | -------------------------------------------------------------------------------- /public/db/mysql/createtable.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 程序名:createtable.cpp,此程序演示开发框架操作MySQL数据库(创建表)。 3 | * 作者:吴从周。 4 | */ 5 | 6 | #include "_mysql.h" // 开发框架操作MySQL的头文件。 7 | 8 | int main(int argc,char *argv[]) 9 | { 10 | connection conn; // 数据库连接类。 11 | 12 | // 登录数据库,返回值:0-成功;其它是失败,存放了MySQL的错误代码。 13 | // 失败代码在conn.m_cda.rc中,失败描述在conn.m_cda.message中。 14 | if (conn.connecttodb("127.0.0.1,root,mysqlpwd,mysql,3306","utf8")!=0) 15 | { 16 | printf("connect database failed.\n%s\n",conn.m_cda.message); return -1; 17 | } 18 | 19 | sqlstatement stmt(&conn); // 操作SQL语句的对象。 20 | 21 | // 准备创建表的SQL语句。 22 | // 超女表girls,超女编号id,超女姓名name,体重weight,报名时间btime,超女说明memo,超女图片pic。 23 | stmt.prepare("create table girls(id bigint(10),\ 24 | name varchar(30),\ 25 | weight decimal(8,2),\ 26 | btime datetime,\ 27 | memo longtext,\ 28 | pic longblob,\ 29 | primary key (id))"); 30 | /* 31 | 1、int prepare(const char *fmt,...),SQL语句可以多行书写。 32 | 2、SQL语句最后的分号可有可无,建议不要写(兼容性考虑)。 33 | 3、SQL语句中不能有说明文字。 34 | 4、可以不用判断stmt.prepare()的返回值,stmt.execute()时再判断。 35 | */ 36 | 37 | // 执行SQL语句,一定要判断返回值,0-成功,其它-失败。 38 | // 失败代码在stmt.m_cda.rc中,失败描述在stmt.m_cda.message中。 39 | if (stmt.execute()!=0) 40 | { 41 | printf("stmt.execute() failed.\n%s\n%s\n",stmt.m_sql,stmt.m_cda.message); return -1; 42 | } 43 | 44 | printf("create table girls ok.\n"); 45 | 46 | return 0; 47 | } 48 | 49 | /* 50 | -- 超女基本信息表。 51 | create table girls(id bigint(10), -- 超女编号。 52 | name varchar(30), -- 超女姓名。 53 | weight decimal(8,2), -- 超女体重。 54 | btime datetime, -- 报名时间。 55 | memo longtext, -- 备注。 56 | pic longblob, -- 照片。 57 | primary key (id)); 58 | */ 59 | 60 | 61 | -------------------------------------------------------------------------------- /public/socket/demo01.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 程序名:demo01.cpp,此程序用于演示socket通讯的客户端。 3 | * 作者:吴从周。 4 | */ 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | int main(int argc,char *argv[]) 15 | { 16 | if (argc!=3) 17 | { 18 | printf("Using:./demo01 ip port\nExample:./demo01 127.0.0.1 5005\n\n"); return -1; 19 | } 20 | 21 | // 第1步:创建客户端的socket。 22 | int sockfd; 23 | if ( (sockfd = socket(AF_INET,SOCK_STREAM,0))==-1) { perror("socket"); return -1; } 24 | 25 | // 第2步:向服务器发起连接请求。 26 | struct hostent* h; 27 | if ( (h = gethostbyname(argv[1])) == 0 ) // 指定服务端的ip地址。 28 | { printf("gethostbyname failed.\n"); close(sockfd); return -1; } 29 | struct sockaddr_in servaddr; 30 | memset(&servaddr,0,sizeof(servaddr)); 31 | servaddr.sin_family = AF_INET; 32 | servaddr.sin_port = htons(atoi(argv[2])); // 指定服务端的通讯端口。 33 | memcpy(&servaddr.sin_addr,h->h_addr,h->h_length); 34 | 35 | if (connect(sockfd, (struct sockaddr *)&servaddr,sizeof(servaddr)) != 0) // 向服务端发起连接清求。 36 | { 37 | perror("connect"); close(sockfd); return -1; 38 | } 39 | 40 | int iret; 41 | char buffer[102400]; 42 | 43 | // 第3步:与服务端通讯,发送一个报文后等待回复,然后再发下一个报文。 44 | for (int ii=0;ii<10;ii++) 45 | { 46 | memset(buffer,0,sizeof(buffer)); 47 | sprintf(buffer,"这是第%d个超级女生,编号%03d。",ii+1,ii+1); 48 | if ( (iret=send(sockfd,buffer,strlen(buffer),0))<=0) // 向服务端发送请求报文。 49 | { perror("send"); break; } 50 | printf("发送:%s\n",buffer); 51 | 52 | memset(buffer,0,sizeof(buffer)); 53 | if ( (iret=recv(sockfd,buffer,sizeof(buffer),0))<=0) // 接收服务端的回应报文。 54 | { 55 | printf("iret=%d\n",iret); break; 56 | } 57 | printf("接收:%s\n",buffer); 58 | 59 | sleep(1); // 每隔一秒后再次发送报文。 60 | } 61 | 62 | // 第4步:关闭socket,释放资源。 63 | close(sockfd); 64 | } 65 | 66 | -------------------------------------------------------------------------------- /public/socket/demo04.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 程序名:demo04.cpp,此程序用于演示粘包的socket服务端。 3 | * 作者:吴从周 4 | */ 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | int main(int argc,char *argv[]) 15 | { 16 | if (argc!=2) 17 | { 18 | printf("Using:./demo04 port\nExample:./demo04 5005\n\n"); return -1; 19 | } 20 | 21 | // 第1步:创建服务端的socket。 22 | int listenfd; 23 | if ( (listenfd = socket(AF_INET,SOCK_STREAM,0))==-1) { perror("socket"); return -1; } 24 | 25 | // 第2步:把服务端用于通讯的地址和端口绑定到socket上。 26 | struct sockaddr_in servaddr; // 服务端地址信息的数据结构。 27 | memset(&servaddr,0,sizeof(servaddr)); 28 | servaddr.sin_family = AF_INET; // 协议族,在socket编程中只能是AF_INET。 29 | servaddr.sin_addr.s_addr = htonl(INADDR_ANY); // 任意ip地址。 30 | servaddr.sin_port = htons(atoi(argv[1])); // 指定通讯端口。 31 | if (bind(listenfd,(struct sockaddr *)&servaddr,sizeof(servaddr)) != 0 ) 32 | { perror("bind"); close(listenfd); return -1; } 33 | 34 | // 第3步:把socket设置为监听模式。 35 | if (listen(listenfd,5) != 0 ) { perror("listen"); close(listenfd); return -1; } 36 | 37 | // 第4步:接受客户端的连接。 38 | int clientfd; // 客户端的socket。 39 | int socklen=sizeof(struct sockaddr_in); // struct sockaddr_in的大小 40 | struct sockaddr_in clientaddr; // 客户端的地址信息。 41 | clientfd=accept(listenfd,(struct sockaddr *)&clientaddr,(socklen_t*)&socklen); 42 | printf("客户端(%s)已连接。\n",inet_ntoa(clientaddr.sin_addr)); 43 | 44 | int iret; 45 | char buffer[1024]; 46 | 47 | // 第5步:与客户端通讯,接收客户端发过来的报文。 48 | while (1) 49 | { 50 | memset(buffer,0,sizeof(buffer)); 51 | 52 | if ( (iret=recv(clientfd,buffer,sizeof(buffer),0))<=0) // 接收客户端的请求报文。 53 | { 54 | printf("iret=%d\n",iret); break; 55 | } 56 | 57 | printf("接收:%s\n",buffer); 58 | } 59 | 60 | // 第6步:关闭socket,释放资源。 61 | close(listenfd); close(clientfd); 62 | } 63 | -------------------------------------------------------------------------------- /public/socket/demo26.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 程序名:demo26.cpp,此程序演示HTTP协议,接收http请求报文。 3 | * 作者:吴从周 4 | */ 5 | #include "../_public.h" 6 | 7 | // 把html文件的内容发送给客户端。 8 | bool SendHtmlFile(const int sockfd,const char *filename); 9 | 10 | int main(int argc,char *argv[]) 11 | { 12 | if (argc!=2) 13 | { 14 | printf("Using:./demo26 port\nExample:./demo26 8080\n\n"); return -1; 15 | } 16 | 17 | CTcpServer TcpServer; 18 | 19 | // 服务端初始化。 20 | if (TcpServer.InitServer(atoi(argv[1]))==false) 21 | { 22 | printf("TcpServer.InitServer(%s) failed.\n",argv[1]); return -1; 23 | } 24 | 25 | // 等待客户端的连接请求。 26 | if (TcpServer.Accept()==false) 27 | { 28 | printf("TcpServer.Accept() failed.\n"); return -1; 29 | } 30 | 31 | printf("客户端(%s)已连接。\n",TcpServer.GetIP()); 32 | 33 | char buffer[102400]; 34 | memset(buffer,0,sizeof(buffer)); 35 | 36 | // 接收http客户端发送过来的报文。 37 | recv(TcpServer.m_connfd,buffer,1000,0); 38 | 39 | printf("%s\n",buffer); 40 | 41 | // 先把响应报文头部发送给客户端。 42 | memset(buffer,0,sizeof(buffer)); 43 | sprintf(buffer,\ 44 | "HTTP/1.1 200 OK\r\n"\ 45 | "Server: demo26\r\n"\ 46 | "Content-Type: text/html;charset=utf-8\r\n"\ 47 | "\r\n"); 48 | // "Content-Length: 108909\r\n\r\n"); 49 | if (Writen(TcpServer.m_connfd,buffer,strlen(buffer))== false) return -1; 50 | 51 | //logfile.Write("%s",buffer); 52 | 53 | // 再把html文件的内容发送给客户端。 54 | SendHtmlFile(TcpServer.m_connfd,"SURF_ZH_20211203191856_28497.csv"); 55 | } 56 | 57 | // 把html文件的内容发送给客户端。 58 | bool SendHtmlFile(const int sockfd,const char *filename) 59 | { 60 | int bytes=0; 61 | char buffer[5000]; 62 | 63 | FILE *fp=NULL; 64 | 65 | if ( (fp=FOPEN(filename,"rb")) == NULL ) return false; 66 | 67 | while (true) 68 | { 69 | memset(buffer,0,sizeof(buffer)); 70 | 71 | if ((bytes=fread(buffer,1,5000,fp)) ==0) break; 72 | 73 | if (Writen(sockfd,buffer,bytes) == false) { fclose(fp); fp=NULL; return false; } 74 | } 75 | 76 | fclose(fp); 77 | 78 | return true; 79 | } 80 | -------------------------------------------------------------------------------- /idc/c/makefile: -------------------------------------------------------------------------------- 1 | # 开发框架头文件路径。 2 | PUBINCL = -I/project/public 3 | 4 | # 开发框架cpp文件名,这里直接包含进来,没有采用链接库,是为了方便调试。 5 | PUBCPP = /project/public/_public.cpp 6 | 7 | # mysql头文件存放路径 8 | MYSQLINCL = -I/usr/local/mysql/include -I/project/public/db/mysql 9 | 10 | # mysql库文件保存路径 11 | MYSQLLIB = -L/usr/local/mysql/lib 12 | 13 | # mysql链接库 14 | MYSQLLIBS = -lmysqlclient 15 | 16 | # 开发框架mysql的cpp文件名,这里直接包含进来,没有采用链接库,是为了方便调试。 17 | MYSQLCPP = /project/public/db/mysql/_mysql.cpp 18 | 19 | # 编译参数。 20 | CFLAGS = -g 21 | 22 | all:crtsurfdata1 crtsurfdata2 crtsurfdata3 crtsurfdata4 crtsurfdata5 crtsurfdata\ 23 | obtcodetodb obtmindtodb 24 | 25 | crtsurfdata1:crtsurfdata1.cpp 26 | g++ $(CFLAGS) -o crtsurfdata1 crtsurfdata1.cpp $(PUBINCL) $(PUBCPP) -lm -lc 27 | cp crtsurfdata1 ../bin/. 28 | 29 | crtsurfdata2:crtsurfdata2.cpp 30 | g++ $(CFLAGS) -o crtsurfdata2 crtsurfdata2.cpp $(PUBINCL) $(PUBCPP) -lm -lc 31 | cp crtsurfdata2 ../bin/. 32 | 33 | crtsurfdata3:crtsurfdata3.cpp 34 | g++ $(CFLAGS) -o crtsurfdata3 crtsurfdata3.cpp $(PUBINCL) $(PUBCPP) -lm -lc 35 | cp crtsurfdata3 ../bin/. 36 | 37 | crtsurfdata4:crtsurfdata4.cpp 38 | g++ $(CFLAGS) -o crtsurfdata4 crtsurfdata4.cpp $(PUBINCL) $(PUBCPP) -lm -lc 39 | cp crtsurfdata4 ../bin/. 40 | 41 | crtsurfdata5:crtsurfdata5.cpp 42 | g++ $(CFLAGS) -o crtsurfdata5 crtsurfdata5.cpp $(PUBINCL) $(PUBCPP) -lm -lc 43 | cp crtsurfdata5 ../bin/. 44 | 45 | crtsurfdata:crtsurfdata.cpp 46 | g++ $(CFLAGS) -o crtsurfdata crtsurfdata.cpp $(PUBINCL) $(PUBCPP) -lm -lc 47 | cp crtsurfdata ../bin/. 48 | 49 | obtcodetodb:obtcodetodb.cpp 50 | g++ $(CFLAGS) -o obtcodetodb obtcodetodb.cpp $(PUBINCL) $(PUBCPP) $(MYSQLINCL) $(MYSQLLIB) $(MYSQLLIBS) $(MYSQLCPP) -lm -lc 51 | cp obtcodetodb ../bin/. 52 | 53 | obtmindtodb:obtmindtodb.cpp idcapp.h idcapp.cpp 54 | g++ $(CFLAGS) -o obtmindtodb obtmindtodb.cpp $(PUBINCL) $(PUBCPP) $(MYSQLINCL) $(MYSQLLIB) $(MYSQLLIBS) $(MYSQLCPP) idcapp.cpp -lm -lc 55 | cp obtmindtodb ../bin/. 56 | 57 | clean: 58 | rm -f crtsurfdata1 crtsurfdata2 crtsurfdata3 crtsurfdata4 crtsurfdata5 crtsurfdata 59 | rm -f obtcodetodb obtmindtodb 60 | -------------------------------------------------------------------------------- /tools/c/deletefiles.cpp: -------------------------------------------------------------------------------- 1 | #include "_public.h" 2 | 3 | // 程序退出和信号2、15的处理函数。 4 | void EXIT(int sig); 5 | 6 | int main(int argc,char *argv[]) 7 | { 8 | // 程序的帮助。 9 | if (argc != 4) 10 | { 11 | printf("\n"); 12 | printf("Using:/project/tools1/bin/deletefiles pathname matchstr timeout\n\n"); 13 | 14 | printf("Example:/project/tools1/bin/deletefiles /log/idc \"*.log.20*\" 0.02\n"); 15 | printf(" /project/tools1/bin/deletefiles /tmp/idc/surfdata \"*.xml,*.json\" 0.01\n"); 16 | printf(" /project/tools1/bin/procctl 300 /project/tools1/bin/deletefiles /log/idc \"*.log.20*\" 0.02\n"); 17 | printf(" /project/tools1/bin/procctl 300 /project/tools1/bin/deletefiles /tmp/idc/surfdata \"*.xml,*.json\" 0.01\n\n"); 18 | 19 | printf("这是一个工具程序,用于删除历史的数据文件或日志文件。\n"); 20 | printf("本程序把pathname目录及子目录中timeout天之前的匹配matchstr文件全部删除,timeout可以是小数。\n"); 21 | printf("本程序不写日志文件,也不会在控制台输出任何信息。\n\n\n"); 22 | 23 | return -1; 24 | } 25 | 26 | // 关闭全部的信号和输入输出。 27 | // 设置信号,在shell状态下可用 "kill + 进程号" 正常终止些进程。 28 | // 但请不要用 "kill -9 +进程号" 强行终止。 29 | // CloseIOAndSignal(true); 30 | signal(SIGINT,EXIT); signal(SIGTERM,EXIT); 31 | 32 | // 获取文件超时的时间点。 33 | char strTimeOut[21]; 34 | LocalTime(strTimeOut,"yyyy-mm-dd hh24:mi:ss",0-(int)(atof(argv[3])*24*60*60)); 35 | 36 | CDir Dir; 37 | // 打开目录,CDir.OpenDir() 38 | if (Dir.OpenDir(argv[1],argv[2],10000,true)==false) 39 | { 40 | printf("Dir.OpenDir(%s) failed.\n",argv[1]); return -1; 41 | } 42 | 43 | // 遍历目录中的文件名。 44 | while (true) 45 | { 46 | // 得到一个文件的信息,CDir.ReadDir() 47 | if (Dir.ReadDir()==false) break; 48 | printf("=%s=\n",Dir.m_FullFileName); 49 | // 与超时的时间点比较,如果更早,就需要删除。 50 | if (strcmp(Dir.m_ModifyTime,strTimeOut)<0) 51 | { 52 | if (REMOVE(Dir.m_FullFileName)==0) 53 | printf("REMOVE %s ok.\n",Dir.m_FullFileName); 54 | else 55 | printf("REMOVE %s failed.\n",Dir.m_FullFileName); 56 | } 57 | } 58 | 59 | return 0; 60 | } 61 | 62 | void EXIT(int sig) 63 | { 64 | printf("程序退出,sig=%d\n\n",sig); 65 | 66 | exit(0); 67 | } 68 | -------------------------------------------------------------------------------- /pthread/book2.cpp: -------------------------------------------------------------------------------- 1 | // 本程序演示线程参数的传递(用强制转换的方法传变量的值)。 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | void *thmain1(void *arg); // 线程1的主函数。 9 | void *thmain2(void *arg); // 线程2的主函数。 10 | void *thmain3(void *arg); // 线程3的主函数。 11 | void *thmain4(void *arg); // 线程4的主函数。 12 | void *thmain5(void *arg); // 线程5的主函数。 13 | int var; 14 | int main(int argc,char *argv[]) 15 | { 16 | pthread_t thid1=0,thid2=0,thid3=0,thid4=0,thid5=0; // 线程id typedef unsigned long pthread_t 17 | 18 | // 创建线程。 19 | var=1; 20 | if (pthread_create(&thid1,NULL,thmain1,(void *)(long)var)!=0) { printf("pthread_create failed.\n"); exit(-1); } 21 | 22 | var=2; 23 | if (pthread_create(&thid2,NULL,thmain2,(void *)(long)var)!=0) { printf("pthread_create failed.\n"); exit(-1); } 24 | 25 | var=3; 26 | if (pthread_create(&thid3,NULL,thmain3,(void *)(long)var)!=0) { printf("pthread_create failed.\n"); exit(-1); } 27 | 28 | var=4; 29 | if (pthread_create(&thid4,NULL,thmain4,(void *)(long)var)!=0) { printf("pthread_create failed.\n"); exit(-1); } 30 | 31 | var=5; 32 | if (pthread_create(&thid5,NULL,thmain5,(void *)(long)var)!=0) { printf("pthread_create failed.\n"); exit(-1); } 33 | 34 | // 等待子线程退出。 35 | printf("join...\n"); 36 | pthread_join(thid1,NULL); 37 | pthread_join(thid2,NULL); 38 | pthread_join(thid3,NULL); 39 | pthread_join(thid4,NULL); 40 | pthread_join(thid5,NULL); 41 | printf("join ok.\n"); 42 | } 43 | 44 | void *thmain1(void *arg) // 线程主函数。 45 | { 46 | printf("var1=%d\n",(int)(long)arg); 47 | printf("线程1开始运行。\n"); 48 | } 49 | 50 | void *thmain2(void *arg) // 线程主函数。 51 | { 52 | printf("var2=%d\n",(int)(long)arg); 53 | printf("线程2开始运行。\n"); 54 | } 55 | 56 | void *thmain3(void *arg) // 线程主函数。 57 | { 58 | printf("var3=%d\n",(int)(long)arg); 59 | printf("线程3开始运行。\n"); 60 | } 61 | 62 | void *thmain4(void *arg) // 线程主函数。 63 | { 64 | printf("var4=%d\n",(int)(long)arg); 65 | printf("线程4开始运行。\n"); 66 | } 67 | 68 | void *thmain5(void *arg) // 线程主函数。 69 | { 70 | printf("var5=%d\n",(int)(long)arg); 71 | printf("线程5开始运行。\n"); 72 | } 73 | -------------------------------------------------------------------------------- /myIdc/c/crtsurfdata2.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * description: crtsurfdata2.cpp 本程序用于生成全国气象站点观测的分钟数据 3 | * author: song zhuozhu 4 | */ 5 | 6 | #include "_public.h" 7 | 8 | // 省 站号 站名 纬度 经度 海拔高度 9 | // 安徽, 58015, 砀山, 34.27, 116.2, 44.2 10 | 11 | struct st_stcode 12 | { 13 | char provname[31]; // 省 14 | char obtid[11]; // 站号 15 | char obtname[31]; // 站名 16 | double lat; // 纬度 17 | double lon; // 经度 18 | double height; // 海拔高度 19 | }; 20 | 21 | // 存放全国气象站点参数的容器 22 | vector vstcode; 23 | 24 | // 把站点参数文件加载到vstcode容器中 25 | bool LoadSTCode(const char* inifile); 26 | 27 | 28 | CLogFile logfile(10); // 日志类, 一般定义为全局变量 29 | 30 | int main(int argc, char *argv[]) 31 | { 32 | // inifile outpath logfile 33 | if (argc != 4) 34 | { 35 | printf("Using:./crtsurfdata1 inifile outpath logfile\n"); 36 | printf("Example:/szz/project/myIdc/bin/crtsurfdata2 /szz/project/myIdc/ini/stcode.ini /tmp/surfdata /log/idc/crtsurfdata.log\n\n"); 37 | 38 | printf("inifle 全国气象站点参数文件名。\n"); 39 | printf("outpath 全国气象站点数据文件存放的目录。\n"); 40 | printf("logfile 本程序运行的日志文件名。\n"); 41 | 42 | return -1; 43 | } 44 | 45 | if (logfile.Open(argv[3], "a+", false) == false) 46 | { 47 | printf("logfile.Open(%s) failed.\n", argv[3]); 48 | return -1; 49 | } 50 | 51 | logfile.Write("crtsurfdata1 开始运行。\n"); 52 | 53 | // 写入业务逻辑代码 54 | 55 | if (LoadSTCode(argv[1]) == false) return -1; 56 | 57 | logfile.Write("crtsurfdata1 运行结束。\n"); 58 | logfile.WriteEx("crtsurfdata1 运行结束。"); 59 | 60 | return 0; 61 | } 62 | 63 | 64 | 65 | // 把站点参数文件加载到vstcode容器中 66 | bool LoadSTCode(const char* inifile) 67 | { 68 | CFile File; 69 | 70 | // 打开站点参数文件 71 | if (File.Open(inifile, "r") == false) 72 | { 73 | // 文件打开失败,返回false 74 | logfile.Write("File.Open(%s) failed.\n", inifile); 75 | return false; 76 | } 77 | 78 | char strBuffer[301]; 79 | 80 | while (true) 81 | { 82 | // 从站点参数文件中读取一行,如果已经读取完,跳出循环 83 | if (File.Fgets(strBuffer, 300, true) == false) 84 | break; 85 | 86 | // 把读取到的一行拆分 87 | 88 | // 把站点参数的每个数据项保存到站点参数结构体中 89 | 90 | // 把站点参数结构体放入站点参数容器 91 | } 92 | 93 | // 关闭文件 94 | 95 | return true; 96 | } -------------------------------------------------------------------------------- /public/db/oracle/inserttable.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 程序名:inserttable.cpp,此程序演示开发框架操作Oracle数据库(向表中插入5条记录)。 3 | * 作者:吴从周。 4 | */ 5 | #include "_ooci.h" // 开发框架操作Oracle的头文件。 6 | 7 | // 定义用于超女信息的结构,与表中的字段对应。 8 | struct st_girls 9 | { 10 | long id; // 超女编号,用long数据类型对应Oracle无小数的number(10)。 11 | char name[30]; // 超女姓名,用char[31]对应Oracle的varchar2(30)。 12 | double weight; // 超女体重,用double数据类型对应Oracle有小数的number(8,2)。 13 | char btime[20]; // 报名时间,用char对应Oracle的date,格式:'yyyy-mm-dd hh24:mi:ssi'。 14 | } stgirls; 15 | 16 | int main(int argc,char *argv[]) 17 | { 18 | connection conn; // 数据库连接类 19 | 20 | // 登录数据库,返回值:0-成功,其它-失败。 21 | // 失败代码在conn.m_cda.rc中,失败描述在conn.m_cda.message中。 22 | if (conn.connecttodb("scott/tiger@snorcl11g_132","Simplified Chinese_China.AL32UTF8")!=0) 23 | { 24 | printf("connect database failed.\n%s\n",conn.m_cda.message); return -1; 25 | } 26 | 27 | sqlstatement stmt(&conn); // 操作SQL语句的对象。 28 | 29 | // 准备插入表的SQL语句。 30 | stmt.prepare("\ 31 | insert into girls(id,name,weight,btime) \ 32 | values(:1,:2,:3,to_date(:4,'yyyy-mm-dd hh24:mi:ss'))"); 33 | // prepare方法不需要判断返回值。 34 | // 为SQL语句绑定输入变量的地址,bindin方法不需要判断返回值。 35 | stmt.bindin(1,&stgirls.id); 36 | stmt.bindin(2, stgirls.name,30); 37 | stmt.bindin(3,&stgirls.weight); 38 | stmt.bindin(4, stgirls.btime,19); 39 | 40 | // 模拟超女数据,向表中插入5条测试数据。 41 | for (int ii=0;ii<5;ii++) 42 | { 43 | memset(&stgirls,0,sizeof(struct st_girls)); // 结构体变量初始化。 44 | 45 | // 为结构体变量的成员赋值。 46 | stgirls.id=ii; // 超女编号。 47 | sprintf(stgirls.name,"西施%05dgirl",ii+1); // 超女姓名。 48 | stgirls.weight=45.35+ii; // 超女体重。 49 | sprintf(stgirls.btime,"2021-08-25 10:33:%02d",ii); // 报名时间。 50 | 51 | // 执行SQL语句,一定要判断返回值,0-成功,其它-失败。 52 | // 失败代码在stmt.m_cda.rc中,失败描述在stmt.m_cda.message中。 53 | if (stmt.execute()!=0) 54 | { 55 | printf("stmt.execute() failed.\n%s\n%s\n",stmt.m_sql,stmt.m_cda.message); return -1; 56 | } 57 | 58 | printf("成功插入了%ld条记录。\n",stmt.m_cda.rpc); // stmt.m_cda.rpc是本次执行SQL影响的记录数。 59 | } 60 | 61 | printf("insert table girls ok.\n"); 62 | 63 | conn.commit(); // 提交数据库事务。 64 | } 65 | -------------------------------------------------------------------------------- /public/db/postgresql/inserttable.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 程序名:inserttable.cpp,此程序演示开发框架操作PostgreSQL数据库(向表中插入5条记录)。 3 | * 作者:吴从周。 4 | */ 5 | #include "_postgresql.h" // 开发框架操作PostgreSQL的头文件。 6 | 7 | // 定义用于超女信息的结构,与表中的字段对应。 8 | struct st_girls 9 | { 10 | long id; // 超女编号,用long数据类型对应Oracle无小数的number(10)。 11 | char name[31]; // 超女姓名,用char[31]对应Oracle的varchar2(30)。 12 | double weight; // 超女体重,用double数据类型对应Oracle有小数的number(8,2)。 13 | char btime[20]; // 报名时间,用char对应Oracle的date,格式:'yyyy-mm-dd hh24:mi:ssi'。 14 | } stgirls; 15 | 16 | int main(int argc,char *argv[]) 17 | { 18 | connection conn; // 数据库连接类 19 | 20 | // 登录数据库,返回值:0-成功,其它-失败。 21 | // 失败代码在conn.m_cda.rc中,失败描述在conn.m_cda.message中。 22 | if (conn.connecttodb("host=172.16.0.15 user=postgres password=pwdidc dbname=postgres port=5432","gbk")!=0) 23 | { 24 | printf("connect database failed.\n%s\n",conn.m_cda.message); return -1; 25 | } 26 | 27 | sqlstatement stmt(&conn); // 操作SQL语句的对象。 28 | 29 | // 准备插入表的SQL语句。 30 | stmt.prepare("\ 31 | insert into girls(id,name,weight,btime) \ 32 | values(:1,:2,:3,to_date(:4,'yyyy-mm-dd hh24:mi:ss'))"); 33 | // prepare方法不需要判断返回值。 34 | // 为SQL语句绑定输入变量的地址,bindin方法不需要判断返回值。 35 | stmt.bindin(1,&stgirls.id); 36 | stmt.bindin(2, stgirls.name,30); 37 | stmt.bindin(3,&stgirls.weight); 38 | stmt.bindin(4, stgirls.btime,19); 39 | 40 | // 模拟超女数据,向表中插入5条测试信息。 41 | for (int ii=1;ii<=5;ii++) 42 | { 43 | memset(&stgirls,0,sizeof(stgirls)); // 结构体变量初始化。 44 | 45 | // 为结构体变量的成员赋值。 46 | stgirls.id=ii; // 超女编号。 47 | sprintf(stgirls.name,"超女%02d",ii); // 超女姓名。 48 | stgirls.weight=ii*2.11; // 超女体重。 49 | strcpy(stgirls.btime,"2018-03-01 12:25:31"); // 报名时间。 50 | 51 | // 执行SQL语句,一定要判断返回值,0-成功,其它-失败。 52 | // 失败代码在stmt.m_cda.rc中,失败描述在stmt.m_cda.message中。 53 | if (stmt.execute() != 0) 54 | { 55 | printf("stmt.execute() failed.\n%s\n%s\n",stmt.m_sql,stmt.m_cda.message); return -1; 56 | } 57 | 58 | printf("成功插入了%ld条记录。\n",stmt.m_cda.rpc); // stmt.m_cda.rpc是本次执行SQL影响的记录数。 59 | } 60 | 61 | printf("insert table girls ok.\n"); 62 | 63 | conn.commit(); // 提交数据库事务。 64 | } 65 | -------------------------------------------------------------------------------- /public/socket/demo11.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 程序名:demo11.cpp,此程序用于演示网银APP软件的客户端。 3 | * 作者:吴从周。 4 | */ 5 | #include "../_public.h" 6 | 7 | CTcpClient TcpClient; 8 | 9 | bool srv001(); // 登录业务。 10 | bool srv002(); // 我的账户(查询余额)。 11 | 12 | int main(int argc,char *argv[]) 13 | { 14 | if (argc!=3) 15 | { 16 | printf("Using:./demo11 ip port\nExample:./demo11 127.0.0.1 5005\n\n"); return -1; 17 | } 18 | 19 | // 向服务端发起连接请求。 20 | if (TcpClient.ConnectToServer(argv[1],atoi(argv[2]))==false) 21 | { 22 | printf("TcpClient.ConnectToServer(%s,%s) failed.\n",argv[1],argv[2]); return -1; 23 | } 24 | 25 | if (srv001()==false) // 登录业务。 26 | { 27 | printf("srv001() failed.\n"); return -1; 28 | } 29 | 30 | if (srv002()==false) // 我的账户(查询余额)。 31 | { 32 | printf("srv002() failed.\n"); return -1; 33 | } 34 | 35 | return 0; 36 | } 37 | 38 | // 登录业务。 39 | bool srv001() 40 | { 41 | char buffer[1024]; 42 | 43 | SPRINTF(buffer,sizeof(buffer),"11392220000123456"); 44 | printf("发送:%s\n",buffer); 45 | if (TcpClient.Write(buffer)==false) return false; // 向服务端发送请求报文。 46 | 47 | memset(buffer,0,sizeof(buffer)); 48 | if (TcpClient.Read(buffer)==false) return false; // 接收服务端的回应报文。 49 | printf("接收:%s\n",buffer); 50 | 51 | // 解析服务端返回的xml。 52 | int iretcode=-1; 53 | GetXMLBuffer(buffer,"retcode",&iretcode); 54 | if (iretcode!=0) { printf("登录失败。\n"); return false; } 55 | 56 | printf("登录成功。\n"); 57 | 58 | return true; 59 | } 60 | 61 | // 我的账户(查询余额)。 62 | bool srv002() 63 | { 64 | char buffer[1024]; 65 | 66 | SPRINTF(buffer,sizeof(buffer),"262620000000001"); 67 | printf("发送:%s\n",buffer); 68 | if (TcpClient.Write(buffer)==false) return false; // 向服务端发送请求报文。 69 | 70 | memset(buffer,0,sizeof(buffer)); 71 | if (TcpClient.Read(buffer)==false) return false; // 接收服务端的回应报文。 72 | printf("接收:%s\n",buffer); 73 | 74 | // 解析服务端返回的xml。 75 | int iretcode=-1; 76 | GetXMLBuffer(buffer,"retcode",&iretcode); 77 | if (iretcode!=0) { printf("查询余额失败。\n"); return false; } 78 | 79 | double ye=0; 80 | GetXMLBuffer(buffer,"ye",&ye); 81 | 82 | printf("查询余额成功(%.2f)。\n",ye); 83 | 84 | return true; 85 | } 86 | 87 | 88 | -------------------------------------------------------------------------------- /pthread/book3.cpp: -------------------------------------------------------------------------------- 1 | // 本程序演示线程参数的传递(不用强制转换的方法,传变量的地址)。 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | void *thmain1(void *arg); // 线程1的主函数。 9 | void *thmain2(void *arg); // 线程2的主函数。 10 | void *thmain3(void *arg); // 线程3的主函数。 11 | void *thmain4(void *arg); // 线程4的主函数。 12 | void *thmain5(void *arg); // 线程5的主函数。 13 | 14 | int main(int argc,char *argv[]) 15 | { 16 | pthread_t thid1=0,thid2=0,thid3=0,thid4=0,thid5=0; // 线程id typedef unsigned long pthread_t 17 | 18 | // 创建线程。 19 | int *var1=new int; *var1=1; 20 | if (pthread_create(&thid1,NULL,thmain1,var1)!=0) { printf("pthread_create failed.\n"); exit(-1); } 21 | 22 | int *var2=new int; *var2=2; 23 | if (pthread_create(&thid2,NULL,thmain2,var2)!=0) { printf("pthread_create failed.\n"); exit(-1); } 24 | 25 | int *var3=new int; *var3=3; 26 | if (pthread_create(&thid3,NULL,thmain3,var3)!=0) { printf("pthread_create failed.\n"); exit(-1); } 27 | 28 | int *var4=new int; *var4=4; 29 | if (pthread_create(&thid4,NULL,thmain4,var4)!=0) { printf("pthread_create failed.\n"); exit(-1); } 30 | 31 | int *var5=new int; *var5=5; 32 | if (pthread_create(&thid5,NULL,thmain5,var5)!=0) { printf("pthread_create failed.\n"); exit(-1); } 33 | 34 | // 等待子线程退出。 35 | printf("join...\n"); 36 | pthread_join(thid1,NULL); 37 | pthread_join(thid2,NULL); 38 | pthread_join(thid3,NULL); 39 | pthread_join(thid4,NULL); 40 | pthread_join(thid5,NULL); 41 | printf("join ok.\n"); 42 | } 43 | 44 | void *thmain1(void *arg) // 线程主函数。 45 | { 46 | printf("var1=%d\n",*(int *)arg); delete (int *)arg; 47 | printf("线程1开始运行。\n"); 48 | } 49 | 50 | void *thmain2(void *arg) // 线程主函数。 51 | { 52 | printf("var2=%d\n",*(int *)arg); delete (int *)arg; 53 | printf("线程2开始运行。\n"); 54 | } 55 | 56 | void *thmain3(void *arg) // 线程主函数。 57 | { 58 | printf("var3=%d\n",*(int *)arg); delete (int *)arg; 59 | printf("线程3开始运行。\n"); 60 | } 61 | 62 | void *thmain4(void *arg) // 线程主函数。 63 | { 64 | printf("var4=%d\n",*(int *)arg); delete (int *)arg; 65 | printf("线程4开始运行。\n"); 66 | } 67 | 68 | void *thmain5(void *arg) // 线程主函数。 69 | { 70 | printf("var5=%d\n",*(int *)arg); delete (int *)arg; 71 | printf("线程5开始运行。\n"); 72 | } 73 | -------------------------------------------------------------------------------- /public/socket/demo02.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 程序名:demo02.cpp,此程序用于演示socket通讯的服务端。 3 | * 作者:吴从周 4 | */ 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | int main(int argc,char *argv[]) 15 | { 16 | if (argc!=2) 17 | { 18 | printf("Using:./demo02 port\nExample:./demo02 5005\n\n"); return -1; 19 | } 20 | 21 | // 第1步:创建服务端的socket。 22 | int listenfd; 23 | if ( (listenfd = socket(AF_INET,SOCK_STREAM,0))==-1) { perror("socket"); return -1; } 24 | 25 | // 第2步:把服务端用于通讯的地址和端口绑定到socket上。 26 | struct sockaddr_in servaddr; // 服务端地址信息的数据结构。 27 | memset(&servaddr,0,sizeof(servaddr)); 28 | servaddr.sin_family = AF_INET; // 协议族,在socket编程中只能是AF_INET。 29 | servaddr.sin_addr.s_addr = htonl(INADDR_ANY); // 任意ip地址。 30 | servaddr.sin_port = htons(atoi(argv[1])); // 指定通讯端口。 31 | if (bind(listenfd,(struct sockaddr *)&servaddr,sizeof(servaddr)) != 0 ) 32 | { perror("bind"); close(listenfd); return -1; } 33 | 34 | int opt = 1; unsigned int len = sizeof(opt); 35 | setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&opt,len); 36 | 37 | // 第3步:把socket设置为监听模式。 38 | if (listen(listenfd,5) != 0 ) { perror("listen"); close(listenfd); return -1; } 39 | 40 | // 第4步:接受客户端的连接。 41 | int clientfd; // 客户端的socket。 42 | int socklen=sizeof(struct sockaddr_in); // struct sockaddr_in的大小 43 | struct sockaddr_in clientaddr; // 客户端的地址信息。 44 | clientfd=accept(listenfd,(struct sockaddr *)&clientaddr,(socklen_t*)&socklen); 45 | printf("客户端(%s)已连接。\n",inet_ntoa(clientaddr.sin_addr)); 46 | 47 | int iret; 48 | char buffer[102400]; 49 | 50 | // 第5步:与客户端通讯,接收客户端发过来的报文后,回复ok。 51 | while (1) 52 | { 53 | memset(buffer,0,sizeof(buffer)); 54 | if ( (iret=recv(clientfd,buffer,sizeof(buffer),0))<=0) // 接收客户端的请求报文。 55 | { 56 | printf("iret=%d\n",iret); break; 57 | } 58 | printf("接收:%s\n",buffer); 59 | 60 | strcpy(buffer,"ok"); 61 | if ( (iret=send(clientfd,buffer,strlen(buffer),0))<=0) // 向客户端发送响应结果。 62 | { perror("send"); break; } 63 | printf("发送:%s\n",buffer); 64 | } 65 | 66 | // 第6步:关闭socket,释放资源。 67 | close(listenfd); close(clientfd); 68 | } 69 | -------------------------------------------------------------------------------- /tools/c/gzipfiles.cpp: -------------------------------------------------------------------------------- 1 | #include "_public.h" 2 | 3 | // 程序退出和信号2、15的处理函数。 4 | void EXIT(int sig); 5 | 6 | int main(int argc,char *argv[]) 7 | { 8 | // 程序的帮助。 9 | if (argc != 4) 10 | { 11 | printf("\n"); 12 | printf("Using:/project/tools1/bin/gzipfiles pathname matchstr timeout\n\n"); 13 | 14 | printf("Example:/project/tools1/bin/gzipfiles /log/idc \"*.log.20*\" 0.02\n"); 15 | printf(" /project/tools1/bin/gzipfiles /tmp/idc/surfdata \"*.xml,*.json\" 0.01\n"); 16 | printf(" /project/tools1/bin/procctl 300 /project/tools1/bin/gzipfiles /log/idc \"*.log.20*\" 0.02\n"); 17 | printf(" /project/tools1/bin/procctl 300 /project/tools1/bin/gzipfiles /tmp/idc/surfdata \"*.xml,*.json\" 0.01\n\n"); 18 | 19 | printf("这是一个工具程序,用于压缩历史的数据文件或日志文件。\n"); 20 | printf("本程序把pathname目录及子目录中timeout天之前的匹配matchstr文件全部压缩,timeout可以是小数。\n"); 21 | printf("本程序不写日志文件,也不会在控制台输出任何信息。\n"); 22 | printf("本程序调用/usr/bin/gzip命令压缩文件。\n\n\n"); 23 | 24 | return -1; 25 | } 26 | 27 | // 关闭全部的信号和输入输出。 28 | // 设置信号,在shell状态下可用 "kill + 进程号" 正常终止些进程。 29 | // 但请不要用 "kill -9 +进程号" 强行终止。 30 | CloseIOAndSignal(true); signal(SIGINT,EXIT); signal(SIGTERM,EXIT); 31 | 32 | // 获取文件超时的时间点。 33 | char strTimeOut[21]; 34 | LocalTime(strTimeOut,"yyyy-mm-dd hh24:mi:ss",0-(int)(atof(argv[3])*24*60*60)); 35 | 36 | CDir Dir; 37 | // 打开目录,CDir.OpenDir() 38 | if (Dir.OpenDir(argv[1],argv[2],10000,true)==false) 39 | { 40 | printf("Dir.OpenDir(%s) failed.\n",argv[1]); return -1; 41 | } 42 | 43 | char strCmd[1024]; // 存放gzip压缩文件的命令。 44 | 45 | // 遍历目录中的文件名。 46 | while (true) 47 | { 48 | // 得到一个文件的信息,CDir.ReadDir() 49 | if (Dir.ReadDir()==false) break; 50 | 51 | // 与超时的时间点比较,如果更早,就需要压缩 52 | if ( (strcmp(Dir.m_ModifyTime,strTimeOut)<0) && (MatchStr(Dir.m_FileName,"*.gz")==false) ) 53 | { 54 | // 压缩文件,调用操作系统的gzip命令。 55 | SNPRINTF(strCmd,sizeof(strCmd),1000,"/usr/bin/gzip -f %s 1>/dev/null 2>/dev/null",Dir.m_FullFileName); 56 | if (system(strCmd)==0) 57 | printf("gzip %s ok.\n",Dir.m_FullFileName); 58 | else 59 | printf("gzip %s failed.\n",Dir.m_FullFileName); 60 | } 61 | } 62 | 63 | return 0; 64 | } 65 | 66 | void EXIT(int sig) 67 | { 68 | printf("程序退出,sig=%d\n\n",sig); 69 | 70 | exit(0); 71 | } 72 | -------------------------------------------------------------------------------- /public/db/oracle/selecttable.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 程序名:selecttable.cpp,此程序演示开发框架操作Oracle数据库(查询表中的记录)。 3 | * 作者:吴从周。 4 | */ 5 | #include "_ooci.h" // 开发框架操作Oracle的头文件。 6 | 7 | // 定义用于超女信息的结构,与表中的字段对应。 8 | struct st_girls 9 | { 10 | long id; // 超女编号,用long数据类型对应Oracle无小数的number(10)。 11 | char name[31]; // 超女姓名,用char[31]对应Oracle的varchar2(30)。 12 | double weight; // 超女体重,用double数据类型对应Oracle有小数的number(8,2)。 13 | char btime[20]; // 报名时间,用char对应Oracle的date,格式:'yyyy-mm-dd hh24:mi:ss'。 14 | } stgirls; 15 | 16 | int main(int argc,char *argv[]) 17 | { 18 | connection conn; // 数据库连接类 19 | 20 | // 登录数据库,返回值:0-成功,其它-失败。 21 | // 失败代码在conn.m_cda.rc中,失败描述在conn.m_cda.message中。 22 | if (conn.connecttodb("scott/tiger@snorcl11g_132","Simplified Chinese_China.AL32UTF8")!=0) 23 | { 24 | printf("connect database failed.\n%s\n",conn.m_cda.message); return -1; 25 | } 26 | 27 | sqlstatement stmt(&conn); // 操作SQL语句的对象。 28 | 29 | int iminid,imaxid; // 查询条件最小和最大的id。 30 | 31 | // 准备查询表的SQL语句。 32 | stmt.prepare("\ 33 | select id,name,weight,to_char(btime,'yyyy-mm-dd hh24:mi:ss') from girls where id>=:1 and id<=:2"); 34 | // prepare方法不需要判断返回值。 35 | // 为SQL语句绑定输入变量的地址,bindin方法不需要判断返回值。 36 | stmt.bindin(1,&iminid); 37 | stmt.bindin(2,&imaxid); 38 | // 为SQL语句绑定输出变量的地址,bindout方法不需要判断返回值。 39 | stmt.bindout(1,&stgirls.id); 40 | stmt.bindout(2, stgirls.name,30); 41 | stmt.bindout(3,&stgirls.weight); 42 | stmt.bindout(4, stgirls.btime,19); 43 | 44 | iminid=2; // 指定待查询记录的最小id的值。 45 | imaxid=4; // 指定待查询记录的最大id的值。 46 | 47 | // 执行SQL语句,一定要判断返回值,0-成功,其它-失败。 48 | // 失败代码在stmt.m_cda.rc中,失败描述在stmt.m_cda.message中。 49 | if (stmt.execute() != 0) 50 | { 51 | printf("stmt.execute() failed.\n%s\n%s\n",stmt.m_sql,stmt.m_cda.message); return -1; 52 | } 53 | 54 | // 本程序执行的是查询语句,执行stmt.execute()后,将会在数据库的缓冲区中产生一个结果集。 55 | while (1) 56 | { 57 | memset(&stgirls,0,sizeof(stgirls)); // 先把结构体变量初始化。 58 | 59 | // 从结果集中获取一条记录,一定要判断返回值,0-成功,1403-无记录,其它-失败。 60 | // 在实际开发中,除了0和1403,其它的情况极少出现。 61 | if (stmt.next() !=0) break; 62 | 63 | // 把获取到的记录的值打印出来。 64 | printf("id=%ld,name=%s,weight=%.02f,btime=%s\n",stgirls.id,stgirls.name,stgirls.weight,stgirls.btime); 65 | } 66 | 67 | // 请注意,stmt.m_cda.rpc变量非常重要,它保存了SQL被执行后影响的记录数。 68 | printf("本次查询了girls表%ld条记录。\n",stmt.m_cda.rpc); 69 | } 70 | 71 | -------------------------------------------------------------------------------- /public/db/postgresql/selecttable.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 程序名:selecttable.cpp,此程序演示开发框架操作PostgreSQL数据库(查询表中的记录)。 3 | * 作者:吴从周。 4 | */ 5 | #include "_postgresql.h" // 开发框架操作PostgreSQL的头文件。 6 | 7 | // 定义用于超女信息的结构,与表中的字段对应。 8 | struct st_girls 9 | { 10 | long id; // 超女编号,用long数据类型对应Oracle无小数的number(10)。 11 | char name[31]; // 超女姓名,用char[31]对应Oracle的varchar2(30)。 12 | double weight; // 超女体重,用double数据类型对应Oracle有小数的number(8,2)。 13 | char btime[20]; // 报名时间,用char对应Oracle的date,格式:'yyyy-mm-dd hh24:mi:ss'。 14 | } stgirls; 15 | 16 | int main(int argc,char *argv[]) 17 | { 18 | connection conn; // 数据库连接类 19 | 20 | // 登录数据库,返回值:0-成功,其它-失败。 21 | // 失败代码在conn.m_cda.rc中,失败描述在conn.m_cda.message中。 22 | if (conn.connecttodb("host=172.16.0.15 user=postgres password=pwdidc dbname=postgres port=5432","gbk")!=0) 23 | { 24 | printf("connect database failed.\n%s\n",conn.m_cda.message); return -1; 25 | } 26 | 27 | sqlstatement stmt(&conn); // 操作SQL语句的对象。 28 | 29 | int iminid,imaxid; // 查询条件最小和最大的id。 30 | 31 | // 准备查询表的SQL语句。 32 | stmt.prepare("\ 33 | select id,name,weight,to_char(btime,'yyyy-mm-dd hh24:mi:ss') from girls where id>=:1 and id<=:2"); 34 | // prepare方法不需要判断返回值。 35 | // 为SQL语句绑定输入变量的地址,bindin方法不需要判断返回值。 36 | stmt.bindin(1,&iminid); 37 | stmt.bindin(2,&imaxid); 38 | // 为SQL语句绑定输出变量的地址,bindout方法不需要判断返回值。 39 | stmt.bindout(1,&stgirls.id); 40 | stmt.bindout(2, stgirls.name,30); 41 | stmt.bindout(3,&stgirls.weight); 42 | stmt.bindout(4, stgirls.btime,19); 43 | 44 | iminid=2; // 指定待查询记录的最小id的值。 45 | imaxid=4; // 指定待查询记录的最大id的值。 46 | 47 | // 执行SQL语句,一定要判断返回值,0-成功,其它-失败。 48 | // 失败代码在stmt.m_cda.rc中,失败描述在stmt.m_cda.message中。 49 | if (stmt.execute() != 0) 50 | { 51 | printf("stmt.execute() failed.\n%s\n%s\n",stmt.m_sql,stmt.m_cda.message); return -1; 52 | } 53 | 54 | // 本程序执行的是查询语句,执行stmt.execute()后,将会在数据库的缓冲区中产生一个结果集。 55 | while (1) 56 | { 57 | memset(&stgirls,0,sizeof(stgirls)); // 先把结构体变量初始化。 58 | 59 | // 从结果集中获取一条记录,一定要判断返回值,0-成功,1403-无记录,其它-失败。 60 | // 在实际开发中,除了0和1403,其它的情况极少出现。 61 | if (stmt.next() !=0) break; 62 | 63 | // 把获取到的记录的值打印出来。 64 | printf("id=%ld,name=%s,weight=%.02f,btime=%s\n",stgirls.id,stgirls.name,stgirls.weight,stgirls.btime); 65 | } 66 | 67 | // 请注意,stmt.m_cda.rpc变量非常重要,它保存了SQL被执行后影响的记录数。 68 | printf("本次查询了girls表%ld条记录。\n",stmt.m_cda.rpc); 69 | } 70 | 71 | -------------------------------------------------------------------------------- /public/db/mysql/updatetable.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 程序名:updatetable.cpp,此程序演示开发框架操作MySQL数据库(修改表中的记录)。 3 | * 作者:吴从周。 4 | */ 5 | 6 | #include "_mysql.h" // 开发框架操作MySQL的头文件。 7 | 8 | int main(int argc,char *argv[]) 9 | { 10 | connection conn; // 数据库连接类。 11 | 12 | // 登录数据库,返回值:0-成功;其它是失败,存放了MySQL的错误代码。 13 | // 失败代码在conn.m_cda.rc中,失败描述在conn.m_cda.message中。 14 | if (conn.connecttodb("127.0.0.1,root,mysqlpwd,mysql,3306","utf8")!=0) 15 | { 16 | printf("connect database failed.\n%s\n",conn.m_cda.message); return -1; 17 | } 18 | 19 | // 定义用于超女信息的结构,与表中的字段对应。 20 | struct st_girls 21 | { 22 | long id; // 超女编号 23 | char name[31]; // 超女姓名 24 | double weight; // 超女体重 25 | char btime[20]; // 报名时间 26 | } stgirls; 27 | 28 | sqlstatement stmt(&conn); // 操作SQL语句的对象。 29 | 30 | // 准备修改表的SQL语句。 31 | stmt.prepare("\ 32 | update girls set name=:1,weight=:2,btime=str_to_date(:3,'%%Y-%%m-%%d %%H:%%i:%%s') where id=:4"); 33 | /* 34 | 注意事项: 35 | 1、参数的序号从1开始,连续、递增,参数也可以用问号表示,但是,问号的兼容性不好,不建议; 36 | 2、SQL语句中的右值才能作为参数,表名、字段名、关键字、函数名等都不能作为参数; 37 | 3、参数可以参与运算或用于函数的参数; 38 | 4、如果SQL语句的主体没有改变,只需要prepare()一次就可以了; 39 | 5、SQL语句中的每个参数,必须调用bindin()绑定变量的地址; 40 | 6、如果SQL语句的主体已改变,prepare()后,需重新用bindin()绑定变量; 41 | 7、prepare()方法有返回值,一般不检查,如果SQL语句有问题,调用execute()方法时能发现; 42 | 8、bindin()方法的返回值固定为0,不用判断返回值; 43 | 9、prepare()和bindin()之后,每调用一次execute(),就执行一次SQL语句,SQL语句的数据来自被绑定变量的值。 44 | */ 45 | stmt.bindin(1, stgirls.name,30); 46 | stmt.bindin(2,&stgirls.weight); 47 | stmt.bindin(3, stgirls.btime,19); 48 | stmt.bindin(4,&stgirls.id); 49 | 50 | // 模拟超女数据,修改超女信息表中的全部记录。 51 | for (int ii=0;ii<5;ii++) 52 | { 53 | memset(&stgirls,0,sizeof(struct st_girls)); // 结构体变量初始化。 54 | 55 | // 为结构体变量的成员赋值。 56 | stgirls.id=ii+1; // 超女编号。 57 | sprintf(stgirls.name,"貂蝉%05dgirl",ii+1); // 超女姓名。 58 | stgirls.weight=ii+48.39; // 超女体重。 59 | sprintf(stgirls.btime,"2021-10-02 11:25:%02d",ii); // 报名时间。 60 | 61 | // 执行SQL语句,一定要判断返回值,0-成功,其它-失败。 62 | // 失败代码在stmt.m_cda.rc中,失败描述在stmt.m_cda.message中。 63 | if (stmt.execute()!=0) 64 | { 65 | printf("stmt.execute() failed.\n%s\n%s\n",stmt.m_sql,stmt.m_cda.message); return -1; 66 | } 67 | 68 | printf("成功修改了%ld条记录。\n",stmt.m_cda.rpc); // stmt.m_cda.rpc是本次执行SQL影响的记录数。 69 | } 70 | 71 | printf("update table girls ok.\n"); 72 | 73 | conn.commit(); // 提交数据库事务。 74 | 75 | return 0; 76 | } 77 | 78 | -------------------------------------------------------------------------------- /public/db/mysql/selecttable.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 程序名:selecttable.cpp,此程序演示开发框架操作MySQL数据库(查询表中的记录)。 3 | * 作者:吴从周。 4 | */ 5 | #include 6 | #include "_mysql.h" // 开发框架操作MySQL的头文件。 7 | 8 | int main(int argc,char *argv[]) 9 | { 10 | connection conn; // 数据库连接类。 11 | 12 | // 登录数据库,返回值:0-成功;其它是失败,存放了MySQL的错误代码。 13 | // 失败代码在conn.m_cda.rc中,失败描述在conn.m_cda.message中。 14 | if (conn.connecttodb("127.0.0.1,root,mysqlpwd,mysql,3306","utf8")!=0) 15 | { 16 | printf("connect database failed.\n%s\n",conn.m_cda.message); return -1; 17 | } 18 | 19 | // 定义用于超女信息的结构,与表中的字段对应。 20 | struct st_girls 21 | { 22 | long id; // 超女编号 23 | char name[31]; // 超女姓名 24 | double weight; // 超女体重 25 | char btime[20]; // 报名时间 26 | } stgirls; 27 | 28 | sqlstatement stmt(&conn); // 操作SQL语句的对象。 29 | 30 | int iminid,imaxid; // 查询条件最小和最大的id。 31 | 32 | // 准备查询表的SQL语句。 33 | stmt.prepare("\ 34 | select id,name,weight,date_format(btime,'%%Y-%%m-%%d %%H:%%i:%%s') from girls where id>=:1 and id<=:2"); 35 | /* 36 | 注意事项: 37 | 1、如果SQL语句的主体没有改变,只需要prepare()一次就可以了; 38 | 2、结果集中的字段,调用bindout()绑定变量的地址; 39 | 3、bindout()方法的返回值固定为0,不用判断返回值; 40 | 4、如果SQL语句的主体已改变,prepare()后,需重新用bindout()绑定变量; 41 | 5、调用execute()方法执行SQL语句,然后再循环调用next()方法获取结果集中的记录; 42 | 6、每调用一次next()方法,从结果集中获取一条记录,字段内容保存在已绑定的变量中。 43 | */ 44 | // 为SQL语句绑定输入变量的地址,bindin方法不需要判断返回值。 45 | stmt.bindin(1,&iminid); 46 | stmt.bindin(2,&imaxid); 47 | // 为SQL语句绑定输出变量的地址,bindout方法不需要判断返回值。 48 | stmt.bindout(1,&stgirls.id); 49 | stmt.bindout(2, stgirls.name,30); 50 | stmt.bindout(3,&stgirls.weight); 51 | stmt.bindout(4, stgirls.btime,19); 52 | 53 | iminid=1; // 指定待查询记录的最小id的值。 54 | imaxid=3; // 指定待查询记录的最大id的值。 55 | 56 | // 执行SQL语句,一定要判断返回值,0-成功,其它-失败。 57 | // 失败代码在stmt.m_cda.rc中,失败描述在stmt.m_cda.message中。 58 | if (stmt.execute() != 0) 59 | { 60 | printf("stmt.execute() failed.\n%s\n%s\n",stmt.m_sql,stmt.m_cda.message); return -1; 61 | } 62 | 63 | // 本程序执行的是查询语句,执行stmt.execute()后,将会在数据库的缓冲区中产生一个结果集。 64 | while (true) 65 | { 66 | memset(&stgirls,0,sizeof(struct st_girls)); // 结构体变量初始化。 67 | 68 | // 从结果集中获取一条记录,一定要判断返回值,0-成功,1403-无记录,其它-失败。 69 | // 在实际开发中,除了0和1403,其它的情况极少出现。 70 | if (stmt.next()!=0) break; 71 | 72 | // 把获取到的记录的值打印出来。 73 | printf("id=%ld,name=%s,weight=%.02f,btime=%s\n",stgirls.id,stgirls.name,stgirls.weight,stgirls.btime); 74 | } 75 | 76 | // 请注意,stmt.m_cda.rpc变量非常重要,它保存了SQL被执行后影响的记录数。 77 | printf("本次查询了girls表%ld条记录。\n",stmt.m_cda.rpc); 78 | 79 | return 0; 80 | } 81 | 82 | -------------------------------------------------------------------------------- /public/socket/makefile: -------------------------------------------------------------------------------- 1 | all:demo01 demo02 demo03 demo04 demo05 demo06 demo07 demo08 demo10 demo11 demo12\ 2 | demo13 demo14 demo31 demo32 demo33 demo20 demo26 demo27 demo28 tcpselect client\ 3 | tcppoll tcpepoll 4 | 5 | demo01:demo01.cpp 6 | g++ -g -o demo01 demo01.cpp -lm -lc 7 | 8 | demo02:demo02.cpp 9 | g++ -g -o demo02 demo02.cpp -lm -lc 10 | 11 | demo03:demo03.cpp 12 | g++ -g -o demo03 demo03.cpp -lm -lc 13 | 14 | demo04:demo04.cpp 15 | g++ -g -o demo04 demo04.cpp -lm -lc 16 | 17 | demo05:demo05.cpp 18 | g++ -g -o demo05 demo05.cpp ../_public.cpp -lm -lc 19 | 20 | demo06:demo06.cpp 21 | g++ -g -o demo06 demo06.cpp ../_public.cpp -lm -lc 22 | 23 | demo07:demo07.cpp 24 | g++ -g -o demo07 demo07.cpp ../_public.cpp -lm -lc 25 | 26 | demo08:demo08.cpp 27 | g++ -g -o demo08 demo08.cpp ../_public.cpp -lm -lc 28 | 29 | demo10:demo10.cpp 30 | g++ -g -o demo10 demo10.cpp ../_public.cpp -lm -lc 31 | 32 | demo11:demo11.cpp 33 | g++ -g -o demo11 demo11.cpp ../_public.cpp -lm -lc 34 | 35 | demo12:demo12.cpp 36 | g++ -g -o demo12 demo12.cpp ../_public.cpp -lm -lc 37 | 38 | demo13:demo13.cpp 39 | g++ -g -o demo13 demo13.cpp ../_public.cpp -lm -lc 40 | 41 | demo14:demo14.cpp 42 | g++ -g -o demo14 demo14.cpp ../_public.cpp -lm -lc 43 | 44 | demo31:demo31.cpp 45 | g++ -g -o demo31 demo31.cpp ../_public.cpp -lm -lc 46 | 47 | demo32:demo32.cpp 48 | g++ -g -o demo32 demo32.cpp ../_public.cpp -lm -lc 49 | 50 | demo33:demo33.cpp 51 | g++ -g -o demo33 demo33.cpp ../_public.cpp -lm -lc 52 | 53 | demo20:demo20.cpp 54 | g++ -g -o demo20 demo20.cpp ../_public.cpp -lpthread -lm -lc 55 | 56 | demo26:demo26.cpp 57 | g++ -g -o demo26 demo26.cpp ../_public.cpp -lm -lc 58 | 59 | demo27:demo27.cpp 60 | g++ -g -o demo27 demo27.cpp ../_public.cpp -lm -lc 61 | 62 | demo28:demo28.cpp 63 | g++ -g -o demo28 demo28.cpp -I/project/public /project/public/_public.cpp -I/oracle/home/rdbms/public -I/project/public/db/oracle -L/oracle/home/lib -L. -lclntsh /project/public/db/oracle/_ooci.cpp -lm -lc 64 | 65 | client:client.cpp 66 | g++ -g -o client client.cpp ../_public.cpp -lm -lc 67 | 68 | tcpselect:tcpselect.cpp 69 | g++ -g -o tcpselect tcpselect.cpp ../_public.cpp -lm -lc 70 | 71 | tcppoll:tcppoll.cpp 72 | g++ -g -o tcppoll tcppoll.cpp ../_public.cpp -lm -lc 73 | 74 | tcpepoll:tcpepoll.cpp 75 | g++ -g -o tcpepoll tcpepoll.cpp ../_public.cpp -lm -lc 76 | 77 | clean: 78 | rm -f demo01 demo02 demo03 demo04 demo05 demo06 demo07 demo08 demo10 demo11 demo12 79 | rm -f demo13 demo14 demo31 demo32 demo33 demo20 demo26 demo27 demo28 tcpselect client 80 | rm -f tcppoll tcpepoll 81 | -------------------------------------------------------------------------------- /public/db/oracle/makefile: -------------------------------------------------------------------------------- 1 | ######################################### 2 | # 请注意,编译时,确定以下几点: 3 | # 1、已安装oracle的客户端或oracle服务端程序,并且必须安装好OCI软件包 4 | # 2、设置好ORACLE_HOME环境变量 5 | # 6 | ######################################### 7 | 8 | # oracle头文件路径 9 | ORAINCL = -I$(ORACLE_HOME)/rdbms/public 10 | 11 | # oracle库文件路径 12 | ORALIB = -L$(ORACLE_HOME)/lib -L. 13 | 14 | # oracle的oci库 15 | ORALIBS = -lclntsh 16 | 17 | #CFLAGS = -O2 18 | CFLAGS = -O2 -Wall 19 | 20 | CFLAGS = -g -Wall -Wno-write-strings #-Wno-unused-variable 21 | 22 | all: createtable inserttable selecttable counttable updatetable deletetable execplsql filetoclob clobtofile filetoblob blobtofile 23 | 24 | createtable: createtable.cpp _ooci.h _ooci.cpp 25 | g++ $(CFLAGS) -o createtable createtable.cpp $(ORAINCL) $(ORALIB) $(ORALIBS) _ooci.cpp -lm -lc 26 | 27 | inserttable: inserttable.cpp _ooci.h _ooci.cpp 28 | g++ $(CFLAGS) -o inserttable inserttable.cpp $(ORAINCL) $(ORALIB) $(ORALIBS) _ooci.cpp -lm -lc 29 | 30 | selecttable: selecttable.cpp _ooci.h _ooci.cpp 31 | g++ $(CFLAGS) -o selecttable selecttable.cpp $(ORAINCL) $(ORALIB) $(ORALIBS) _ooci.cpp -lm -lc 32 | 33 | counttable: counttable.cpp _ooci.h _ooci.cpp 34 | g++ $(CFLAGS) -o counttable counttable.cpp $(ORAINCL) $(ORALIB) $(ORALIBS) _ooci.cpp -lm -lc 35 | 36 | updatetable: updatetable.cpp _ooci.h _ooci.cpp 37 | g++ $(CFLAGS) -o updatetable updatetable.cpp $(ORAINCL) $(ORALIB) $(ORALIBS) _ooci.cpp -lm -lc 38 | 39 | deletetable: deletetable.cpp _ooci.h _ooci.cpp 40 | g++ $(CFLAGS) -o deletetable deletetable.cpp $(ORAINCL) $(ORALIB) $(ORALIBS) _ooci.cpp -lm -lc 41 | 42 | execplsql: execplsql.cpp _ooci.h _ooci.cpp 43 | g++ $(CFLAGS) -o execplsql execplsql.cpp $(ORAINCL) $(ORALIB) $(ORALIBS) _ooci.cpp -lm -lc 44 | 45 | filetoclob: filetoclob.cpp _ooci.h _ooci.cpp 46 | g++ $(CFLAGS) -o filetoclob filetoclob.cpp $(ORAINCL) $(ORALIB) $(ORALIBS) _ooci.cpp -lm -lc 47 | 48 | clobtofile: clobtofile.cpp _ooci.h _ooci.cpp 49 | g++ $(CFLAGS) -o clobtofile clobtofile.cpp $(ORAINCL) $(ORALIB) $(ORALIBS) _ooci.cpp -lm -lc 50 | 51 | filetoblob: filetoblob.cpp _ooci.h _ooci.cpp 52 | g++ $(CFLAGS) -o filetoblob filetoblob.cpp $(ORAINCL) $(ORALIB) $(ORALIBS) _ooci.cpp -lm -lc 53 | 54 | blobtofile: blobtofile.cpp _ooci.h _ooci.cpp 55 | g++ $(CFLAGS) -o blobtofile blobtofile.cpp $(ORAINCL) $(ORALIB) $(ORALIBS) _ooci.cpp -lm -lc 56 | 57 | 58 | clean: 59 | rm -rf createtable inserttable selecttable counttable updatetable deletetable execplsql filetoclob clobtofile filetoblob blobtofile 60 | rm -rf memo_out.txt pic_out.jpg 61 | -------------------------------------------------------------------------------- /public/db/mysql/inserttable.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 程序名:inserttable.cpp,此程序演示开发框架操作MySQL数据库(向表中插入5条记录)。 3 | * 作者:吴从周。 4 | */ 5 | #include 6 | #include "_mysql.h" // 开发框架操作MySQL的头文件。 7 | 8 | int main(int argc,char *argv[]) 9 | { 10 | connection conn; // 数据库连接类。 11 | 12 | // 登录数据库,返回值:0-成功;其它是失败,存放了MySQL的错误代码。 13 | // 失败代码在conn.m_cda.rc中,失败描述在conn.m_cda.message中。 14 | if (conn.connecttodb("127.0.0.1,root,mysqlpwd,mysql,3306","utf8")!=0) 15 | { 16 | printf("connect database failed.\n%s\n",conn.m_cda.message); return -1; 17 | } 18 | 19 | // 定义用于超女信息的结构,与表中的字段对应。 20 | struct st_girls 21 | { 22 | long id; // 超女编号 23 | char name[31]; // 超女姓名 24 | double weight; // 超女体重 25 | char btime[20]; // 报名时间 26 | } stgirls; 27 | 28 | sqlstatement stmt(&conn); // 操作SQL语句的对象。 29 | 30 | // 准备插入表的SQL语句。 31 | stmt.prepare("\ 32 | insert into girls(id,name,weight,btime) values(:1+1,:2,:3+45.35,str_to_date(:4,'%%Y-%%m-%%d %%H:%%i:%%s'))"); 33 | //insert into girls(id,name,weight,btime) values(?+1,?,?+45.35,to_date(?,'yyyy-mm-dd hh24:mi:ss'))"); 34 | /* 35 | 注意事项: 36 | 1、参数的序号从1开始,连续、递增,参数也可以用问号表示,但是,问号的兼容性不好,不建议; 37 | 2、SQL语句中的右值才能作为参数,表名、字段名、关键字、函数名等都不能作为参数; 38 | 3、参数可以参与运算或用于函数的参数; 39 | 4、如果SQL语句的主体没有改变,只需要prepare()一次就可以了; 40 | 5、SQL语句中的每个参数,必须调用bindin()绑定变量的地址; 41 | 6、如果SQL语句的主体已改变,prepare()后,需重新用bindin()绑定变量; 42 | 7、prepare()方法有返回值,一般不检查,如果SQL语句有问题,调用execute()方法时能发现; 43 | 8、bindin()方法的返回值固定为0,不用判断返回值; 44 | 9、prepare()和bindin()之后,每调用一次execute(),就执行一次SQL语句,SQL语句的数据来自被绑定变量的值。 45 | */ 46 | stmt.bindin(1,&stgirls.id); 47 | stmt.bindin(2, stgirls.name,30); 48 | stmt.bindin(3,&stgirls.weight); 49 | stmt.bindin(4, stgirls.btime,19); 50 | 51 | // 模拟超女数据,向表中插入5条测试数据。 52 | for (int ii=0;ii<5;ii++) 53 | { 54 | memset(&stgirls,0,sizeof(struct st_girls)); // 结构体变量初始化。 55 | 56 | // 为结构体变量的成员赋值。 57 | stgirls.id=ii; // 超女编号。 58 | sprintf(stgirls.name,"西施%05dgirl",ii+1); // 超女姓名。 59 | stgirls.weight=ii; // 超女体重。 60 | sprintf(stgirls.btime,"2021-08-25 10:33:%02d",ii); // 报名时间。 61 | 62 | // 执行SQL语句,一定要判断返回值,0-成功,其它-失败。 63 | // 失败代码在stmt.m_cda.rc中,失败描述在stmt.m_cda.message中。 64 | if (stmt.execute()!=0) 65 | { 66 | printf("stmt.execute() failed.\n%s\n%s\n",stmt.m_sql,stmt.m_cda.message); return -1; 67 | } 68 | 69 | printf("成功插入了%ld条记录。\n",stmt.m_cda.rpc); // stmt.m_cda.rpc是本次执行SQL影响的记录数。 70 | } 71 | 72 | printf("insert table girls ok.\n"); 73 | 74 | conn.commit(); // 提交数据库事务。 75 | 76 | return 0; 77 | } 78 | 79 | -------------------------------------------------------------------------------- /tools/c/execsql.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * execsql.cpp,这是一个工具程序,用于执行一个sql脚本文件。 3 | * 作者:吴从周。 4 | */ 5 | #include "_public.h" 6 | #include "_mysql.h" 7 | 8 | CLogFile logfile; 9 | 10 | connection conn; 11 | 12 | CPActive PActive; 13 | 14 | void EXIT(int sig); 15 | 16 | int main(int argc,char *argv[]) 17 | { 18 | // 帮助文档。 19 | if (argc!=5) 20 | { 21 | printf("\n"); 22 | printf("Using:./execsql sqlfile connstr charset logfile\n"); 23 | 24 | printf("Example:/project/tools1/bin/procctl 120 /project/tools1/bin/execsql /project/idc/sql/cleardata.sql \"127.0.0.1,root,mysqlpwd,mysql,3306\" utf8 /log/idc/execsql.log\n\n"); 25 | 26 | printf("这是一个工具程序,用于执行一个sql脚本文件。\n"); 27 | printf("sqlfile sql脚本文件名,每条sql语句可以多行书写,分号表示一条sql语句的结束,不支持注释。\n"); 28 | printf("connstr 数据库连接参数:ip,username,password,dbname,port\n"); 29 | printf("charset 数据库的字符集。\n"); 30 | printf("logfile 本程序运行的日志文件名。\n\n"); 31 | 32 | return -1; 33 | } 34 | 35 | // 关闭全部的信号和输入输出。 36 | // 设置信号,在shell状态下可用 "kill + 进程号" 正常终止些进程。 37 | // 但请不要用 "kill -9 +进程号" 强行终止。 38 | CloseIOAndSignal(); signal(SIGINT,EXIT); signal(SIGTERM,EXIT); 39 | 40 | // 打开日志文件。 41 | if (logfile.Open(argv[4],"a+")==false) 42 | { 43 | printf("打开日志文件失败(%s)。\n",argv[4]); return -1; 44 | } 45 | 46 | PActive.AddPInfo(500,"obtcodetodb"); // 进程的心跳,时间长的点。 47 | // 注意,在调试程序的时候,可以启用类似以下的代码,防止超时。 48 | // PActive.AddPInfo(5000,"obtcodetodb"); 49 | 50 | // 连接数据库,不启用事务。 51 | if (conn.connecttodb(argv[2],argv[3],1)!=0) 52 | { 53 | logfile.Write("connect database(%s) failed.\n%s\n",argv[2],conn.m_cda.message); return -1; 54 | } 55 | 56 | logfile.Write("connect database(%s) ok.\n",argv[2]); 57 | 58 | CFile File; 59 | 60 | // 打开SQL文件。 61 | if (File.Open(argv[1],"r")==false) 62 | { 63 | logfile.Write("File.Open(%s) failed.\n",argv[1]); EXIT(-1); 64 | } 65 | 66 | char strsql[1001]; // 存放从SQL文件中读取的SQL语句。 67 | 68 | while (true) 69 | { 70 | memset(strsql,0,sizeof(strsql)); 71 | 72 | // 从SQL文件中读取以分号结束的一行。 73 | if (File.FFGETS(strsql,1000,";")==false) break; 74 | 75 | // 如果第一个字符是#,注释,不执行。 76 | if (strsql[0]=='#') continue; 77 | 78 | // 删除掉SQL语句最后的分号。 79 | char *pp=strstr(strsql,";"); 80 | if (pp==0) continue; 81 | pp[0]=0; 82 | 83 | logfile.Write("%s\n",strsql); 84 | 85 | int iret=conn.execute(strsql); // 执行SQL语句。 86 | 87 | // 把SQL语句执行结果写日志。 88 | if (iret==0) logfile.Write("exec ok(rpc=%d).\n",conn.m_cda.rpc); 89 | else logfile.Write("exec failed(%s).\n",conn.m_cda.message); 90 | 91 | PActive.UptATime(); // 进程的心跳。 92 | } 93 | 94 | logfile.WriteEx("\n"); 95 | 96 | return 0; 97 | } 98 | 99 | void EXIT(int sig) 100 | { 101 | logfile.Write("程序退出,sig=%d\n\n",sig); 102 | 103 | conn.disconnect(); 104 | 105 | exit(0); 106 | } 107 | -------------------------------------------------------------------------------- /idc/c/obtmindtodb1.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * obtmindtodb.cpp,本程序用于把全国站点分钟观测数据入库到T_ZHOBTMIND表中,支持xml和csv两种文件格式。 3 | * 作者:吴从周。 4 | */ 5 | #include "_public.h" 6 | #include "_mysql.h" 7 | 8 | CLogFile logfile; 9 | 10 | connection conn; 11 | 12 | CPActive PActive; 13 | 14 | void EXIT(int sig); 15 | 16 | // 业务处理主函数。 17 | bool _obtmindtodb(char *pathname,char *connstr,char *charset); 18 | 19 | int main(int argc,char *argv[]) 20 | { 21 | // 帮助文档。 22 | if (argc!=5) 23 | { 24 | printf("\n"); 25 | printf("Using:./obtmindtodb pathname connstr charset logfile\n"); 26 | 27 | printf("Example:/project/tools1/bin/procctl 10 /project/idc1/bin/obtmindtodb /idcdata/surfdata \"127.0.0.1,root,mysqlpwd,mysql,3306\" utf8 /log/idc/obtmindtodb.log\n\n"); 28 | 29 | printf("本程序用于把全国站点分钟观测数据保存到数据库的T_ZHOBTMIND表中,数据只插入,不更新。\n"); 30 | printf("pathname 全国站点分钟观测数据文件存放的目录。\n"); 31 | printf("connstr 数据库连接参数:ip,username,password,dbname,port\n"); 32 | printf("charset 数据库的字符集。\n"); 33 | printf("logfile 本程序运行的日志文件名。\n"); 34 | printf("程序每10秒运行一次,由procctl调度。\n\n\n"); 35 | 36 | return -1; 37 | } 38 | 39 | // 关闭全部的信号和输入输出。 40 | // 设置信号,在shell状态下可用 "kill + 进程号" 正常终止些进程。 41 | // 但请不要用 "kill -9 +进程号" 强行终止。 42 | CloseIOAndSignal(); signal(SIGINT,EXIT); signal(SIGTERM,EXIT); 43 | 44 | // 打开日志文件。 45 | if (logfile.Open(argv[4],"a+")==false) 46 | { 47 | printf("打开日志文件失败(%s)。\n",argv[4]); return -1; 48 | } 49 | 50 | // PActive.AddPInfo(30,"obtmindtodb"); // 进程的心跳,30秒足够。 51 | // 注意,在调试程序的时候,可以启用类似以下的代码,防止超时。 52 | PActive.AddPInfo(5000,"obtmindtodb"); 53 | 54 | // 业务处理主函数。 55 | _obtmindtodb(argv[1],argv[2],argv[3]); 56 | 57 | /* 58 | // 连接数据库。 59 | if (conn.connecttodb(argv[2],argv[3])!=0) 60 | { 61 | logfile.Write("connect database(%s) failed.\n%s\n",argv[2],conn.m_cda.message); return -1; 62 | } 63 | 64 | logfile.Write("connect database(%s) ok.\n",argv[2]); 65 | 66 | // 提交事务。 67 | conn.commit(); 68 | */ 69 | 70 | return 0; 71 | } 72 | 73 | void EXIT(int sig) 74 | { 75 | logfile.Write("程序退出,sig=%d\n\n",sig); 76 | 77 | conn.disconnect(); 78 | 79 | exit(0); 80 | } 81 | 82 | // 业务处理主函数。 83 | bool _obtmindtodb(char *pathname,char *connstr,char *charset) 84 | { 85 | CDir Dir; 86 | 87 | // 打开目录。 88 | if (Dir.OpenDir(pathname,"*.xml")==false) 89 | { 90 | logfile.Write("Dir.OpenDir(%s) failed.\n",pathname); return false; 91 | } 92 | 93 | while (true) 94 | { 95 | // 读取目录,得到一个数据文件名。 96 | if (Dir.ReadDir()==false) break; 97 | 98 | logfile.Write("filename=%s\n",Dir.m_FullFileName); 99 | 这个程序的流程稍微复杂一点,所以我又采用了按部就搬的编程方法,一步一步的实现功能。 100 | 现在达到了一个小目标,把程序先做一个备份。 101 | // 打开文件。 102 | 103 | /* 104 | while (true) 105 | { 106 | // 处理文件中的每一行。 107 | } 108 | */ 109 | 110 | // 删除文件、提交事务。 111 | } 112 | 113 | return true; 114 | } 115 | 116 | 117 | 118 | 119 | -------------------------------------------------------------------------------- /idc/c/crtsurfdata2.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 程序名:crtsurfdata2.cpp 本程序用于生成全国气象站点观测的分钟数据。 3 | * 作者:吴从周。 4 | */ 5 | 6 | #include "_public.h" 7 | 8 | // 全国气象站点参数结构体。 9 | struct st_stcode 10 | { 11 | char provname[31]; // 省 12 | char obtid[11]; // 站号 13 | char obtname[31]; // 站名 14 | double lat; // 纬度 15 | double lon; // 经度 16 | double height; // 海拔高度 17 | }; 18 | 19 | // 存放全国气象站点参数的容器。 20 | vector vstcode; 21 | 22 | // 把站点参数文件中加载到vstcode容器中。 23 | bool LoadSTCode(const char *inifile); 24 | 25 | CLogFile logfile; // 日志类。 26 | 27 | int main(int argc,char *argv[]) 28 | { 29 | if (argc!=4) 30 | { 31 | // 如果参数非法,给出帮助文档。 32 | printf("Using:./crtsurfdata2 inifile outpath logfile\n"); 33 | printf("Example:/project/idc1/bin/crtsurfdata2 /project/idc1/ini/stcode.ini /tmp/surfdata /log/idc/crtsurfdata2.log\n\n"); 34 | 35 | printf("inifile 全国气象站点参数文件名。\n"); 36 | printf("outpath 全国气象站点数据文件存放的目录。\n"); 37 | printf("logfile 本程序运行的日志文件名。\n\n"); 38 | 39 | return -1; 40 | } 41 | 42 | // 打开程序的日志文件。 43 | if (logfile.Open(argv[3],"a+",false)==false) 44 | { 45 | printf("logfile.Open(%s) failed.\n",argv[3]); return -1; 46 | } 47 | 48 | logfile.Write("crtsurfdata2 开始运行。\n"); 49 | 50 | // 把站点参数文件中加载到vstcode容器中。 51 | if (LoadSTCode(argv[1])==false) return -1; 52 | 53 | 54 | logfile.WriteEx("crtsurfdata2 运行结束。\n"); 55 | 56 | return 0; 57 | } 58 | 59 | // 把站点参数文件中加载到vstcode容器中。 60 | bool LoadSTCode(const char *inifile) 61 | { 62 | CFile File; 63 | 64 | // 打开站点参数文件。 65 | if (File.Open(inifile,"r")==false) 66 | { 67 | logfile.Write("File.Open(%s) failed.\n",inifile); return false; 68 | } 69 | 70 | char strBuffer[301]; 71 | 72 | CCmdStr CmdStr; 73 | 74 | struct st_stcode stcode; 75 | 76 | while (true) 77 | { 78 | // 从站点参数文件中读取一行,如果已读取完,跳出循环。 79 | if (File.Fgets(strBuffer,300,true)==false) break; 80 | 81 | // 把读取到的一行拆分。 82 | CmdStr.SplitToCmd(strBuffer,",",true); 83 | 84 | if (CmdStr.CmdCount()!=6) continue; // 扔掉无效的行。 85 | 86 | // 把站点参数的每个数据项保存到站点参数结构体中。 87 | memset(&stcode,0,sizeof(struct st_stcode)); 88 | CmdStr.GetValue(0, stcode.provname,30); // 省 89 | CmdStr.GetValue(1, stcode.obtid,10); // 站号 90 | CmdStr.GetValue(2, stcode.obtname,30); // 站名 91 | CmdStr.GetValue(3,&stcode.lat); // 纬度 92 | CmdStr.GetValue(4,&stcode.lon); // 经度 93 | CmdStr.GetValue(5,&stcode.height); // 海拔高度 94 | 95 | // 把站点参数结构体放入站点参数容器。 96 | vstcode.push_back(stcode); 97 | } 98 | 99 | /* 100 | for (int ii=0;ii0) { TcpServer.CloseClient(); continue; } // 父进程继续回到Accept()。 54 | 55 | // 子进程重新设置退出信号。 56 | signal(SIGINT,ChldEXIT); signal(SIGTERM,ChldEXIT); 57 | 58 | TcpServer.CloseListen(); 59 | 60 | // 子进程与客户端进行通讯,处理业务。 61 | char buffer[102400]; 62 | 63 | // 与客户端通讯,接收客户端发过来的报文后,回复ok。 64 | while (1) 65 | { 66 | memset(buffer,0,sizeof(buffer)); 67 | if (TcpServer.Read(buffer)==false) break; // 接收客户端的请求报文。 68 | logfile.Write("接收:%s\n",buffer); 69 | 70 | strcpy(buffer,"ok"); 71 | if (TcpServer.Write(buffer)==false) break; // 向客户端发送响应结果。 72 | logfile.Write("发送:%s\n",buffer); 73 | } 74 | 75 | ChldEXIT(0); 76 | } 77 | } 78 | 79 | // 父进程退出函数。 80 | void FathEXIT(int sig) 81 | { 82 | // 以下代码是为了防止信号处理函数在执行的过程中被信号中断。 83 | signal(SIGINT,SIG_IGN); signal(SIGTERM,SIG_IGN); 84 | 85 | logfile.Write("父进程退出,sig=%d。\n",sig); 86 | 87 | TcpServer.CloseListen(); // 关闭监听的socket。 88 | 89 | kill(0,15); // 通知全部的子进程退出。 90 | 91 | exit(0); 92 | } 93 | 94 | // 子进程退出函数。 95 | void ChldEXIT(int sig) 96 | { 97 | // 以下代码是为了防止信号处理函数在执行的过程中被信号中断。 98 | signal(SIGINT,SIG_IGN); signal(SIGTERM,SIG_IGN); 99 | 100 | logfile.Write("子进程退出,sig=%d。\n",sig); 101 | 102 | TcpServer.CloseClient(); // 关闭客户端的socket。 103 | 104 | exit(0); 105 | } 106 | -------------------------------------------------------------------------------- /public/socket/demo13.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 程序名:demo13.cpp,此程序用于演示网银APP软件的客户端,增加了心跳报文。 3 | * 作者:吴从周。 4 | */ 5 | #include "../_public.h" 6 | 7 | CTcpClient TcpClient; 8 | 9 | bool srv000(); // 心跳。 10 | bool srv001(); // 登录业务。 11 | bool srv002(); // 我的账户(查询余额)。 12 | 13 | int main(int argc,char *argv[]) 14 | { 15 | if (argc!=3) 16 | { 17 | printf("Using:./demo13 ip port\nExample:./demo13 127.0.0.1 5005\n\n"); return -1; 18 | } 19 | 20 | // 向服务端发起连接请求。 21 | if (TcpClient.ConnectToServer(argv[1],atoi(argv[2]))==false) 22 | { 23 | printf("TcpClient.ConnectToServer(%s,%s) failed.\n",argv[1],argv[2]); return -1; 24 | } 25 | 26 | // 登录业务。 27 | if (srv001()==false) { printf("srv001() failed.\n"); return -1; } 28 | 29 | sleep(3); 30 | 31 | // 我的账户(查询余额)。 32 | if (srv002()==false) { printf("srv002() failed.\n"); return -1; } 33 | 34 | sleep(10); 35 | 36 | for (int ii=3;ii<5;ii++) 37 | { 38 | if (srv000()==false) break; 39 | 40 | sleep(ii); 41 | } 42 | 43 | // 我的账户(查询余额)。 44 | if (srv002()==false) { printf("srv002() failed.\n"); return -1; } 45 | 46 | return 0; 47 | } 48 | 49 | // 心跳。 50 | bool srv000() 51 | { 52 | char buffer[1024]; 53 | 54 | SPRINTF(buffer,sizeof(buffer),"0"); 55 | printf("发送:%s\n",buffer); 56 | if (TcpClient.Write(buffer)==false) return false; // 向服务端发送请求报文。 57 | 58 | memset(buffer,0,sizeof(buffer)); 59 | if (TcpClient.Read(buffer)==false) return false; // 接收服务端的回应报文。 60 | printf("接收:%s\n",buffer); 61 | 62 | return true; 63 | } 64 | 65 | // 登录业务。 66 | bool srv001() 67 | { 68 | char buffer[1024]; 69 | 70 | SPRINTF(buffer,sizeof(buffer),"11392220000123456"); 71 | printf("发送:%s\n",buffer); 72 | if (TcpClient.Write(buffer)==false) return false; // 向服务端发送请求报文。 73 | 74 | memset(buffer,0,sizeof(buffer)); 75 | if (TcpClient.Read(buffer)==false) return false; // 接收服务端的回应报文。 76 | printf("接收:%s\n",buffer); 77 | 78 | // 解析服务端返回的xml。 79 | int iretcode=-1; 80 | GetXMLBuffer(buffer,"retcode",&iretcode); 81 | if (iretcode!=0) { printf("登录失败。\n"); return false; } 82 | 83 | printf("登录成功。\n"); 84 | 85 | return true; 86 | } 87 | 88 | // 我的账户(查询余额)。 89 | bool srv002() 90 | { 91 | char buffer[1024]; 92 | 93 | SPRINTF(buffer,sizeof(buffer),"262620000000001"); 94 | printf("发送:%s\n",buffer); 95 | if (TcpClient.Write(buffer)==false) return false; // 向服务端发送请求报文。 96 | 97 | memset(buffer,0,sizeof(buffer)); 98 | if (TcpClient.Read(buffer)==false) return false; // 接收服务端的回应报文。 99 | printf("接收:%s\n",buffer); 100 | 101 | // 解析服务端返回的xml。 102 | int iretcode=-1; 103 | GetXMLBuffer(buffer,"retcode",&iretcode); 104 | if (iretcode!=0) { printf("查询余额失败。\n"); return false; } 105 | 106 | double ye=0; 107 | GetXMLBuffer(buffer,"ye",&ye); 108 | 109 | printf("查询余额成功(%.2f)。\n",ye); 110 | 111 | return true; 112 | } 113 | 114 | 115 | -------------------------------------------------------------------------------- /tools/c/checkproc.cpp: -------------------------------------------------------------------------------- 1 | #include "_public.h" 2 | 3 | // 程序运行的日志。 4 | CLogFile logfile; 5 | 6 | int main(int argc,char *argv[]) 7 | { 8 | // 程序的帮助。 9 | if (argc != 2) 10 | { 11 | printf("\n"); 12 | printf("Using:./checkproc logfilename\n"); 13 | 14 | printf("Example:/project/tools1/bin/procctl 10 /project/tools1/bin/checkproc /tmp/log/checkproc.log\n\n"); 15 | 16 | printf("本程序用于检查后台服务程序是否超时,如果已超时,就终止它。\n"); 17 | printf("注意:\n"); 18 | printf(" 1)本程序由procctl启动,运行周期建议为10秒。\n"); 19 | printf(" 2)为了避免被普通用户误杀,本程序应该用root用户启动。\n"); 20 | printf(" 3)如果要停止本程序,只能用killall -9 终止。\n\n\n"); 21 | 22 | return 0; 23 | } 24 | 25 | // 忽略全部的信号和IO,不希望程序被干扰。 26 | CloseIOAndSignal(true); 27 | 28 | // 打开日志文件。 29 | if (logfile.Open(argv[1],"a+")==false) 30 | { printf("logfile.Open(%s) failed.\n",argv[1]); return -1; } 31 | 32 | int shmid=0; 33 | 34 | // 创建/获取共享内存,键值为SHMKEYP,大小为MAXNUMP个st_procinfo结构体的大小。 35 | if ( (shmid = shmget((key_t)SHMKEYP, MAXNUMP*sizeof(struct st_procinfo), 0666|IPC_CREAT)) == -1) 36 | { 37 | logfile.Write("创建/获取共享内存(%x)失败。\n",SHMKEYP); return false; 38 | } 39 | 40 | // 将共享内存连接到当前进程的地址空间。 41 | struct st_procinfo *shm=(struct st_procinfo *)shmat(shmid, 0, 0); 42 | 43 | // 遍历共享内存中全部的记录。 44 | for (int ii=0;iipid,(shm+ii)->pname); 60 | memset(shm+ii,0,sizeof(struct st_procinfo)); // 从共享内存中删除该记录。 61 | continue; 62 | } 63 | 64 | time_t now=time(0); // 取当前时间。 65 | 66 | // 如果进程未超时,continue; 67 | if (now-shm[ii].atimepid,(shm+ii)->pname); 71 | 72 | // 发送信号15,尝试正常终止进程。 73 | kill(shm[ii].pid,15); 74 | 75 | // 每隔1秒判断一次进程是否存在,累计5秒,一般来说,5秒的时间足够让进程退出。 76 | for (int jj=0;jj<5;jj++) 77 | { 78 | sleep(1); 79 | iret=kill(shm[ii].pid,0); // 向进程发送信号0,判断它是否还存在。 80 | if (iret==-1) break; // 进程已退出。 81 | } 82 | 83 | // 如果进程仍存在,就发送信号9,强制终止它。 84 | if (iret==-1) 85 | logfile.Write("进程pid=%d(%s)已经正常终止。\n",(shm+ii)->pid,(shm+ii)->pname); 86 | else 87 | { 88 | kill(shm[ii].pid,9); // 如果进程仍存在,就发送信号9,强制终止它。 89 | logfile.Write("进程pid=%d(%s)已经强制终止。\n",(shm+ii)->pid,(shm+ii)->pname); 90 | } 91 | 92 | // 从共享内存中删除已超时进程的心跳记录。 93 | memset(shm+ii,0,sizeof(struct st_procinfo)); // 从共享内存中删除该记录。 94 | } 95 | 96 | // 把共享内存从当前进程中分离。 97 | shmdt(shm); 98 | 99 | return 0; 100 | } 101 | -------------------------------------------------------------------------------- /pthread/book19.cpp: -------------------------------------------------------------------------------- 1 | // 本程序演示只用信号量实现高速缓存。 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | using namespace std; 12 | 13 | // 缓存队列消息的结构体。 14 | struct st_message 15 | { 16 | int mesgid; // 消息的id。 17 | char message[1024]; // 消息的内容。 18 | }stmesg; 19 | 20 | vector vcache; // 用vector容器做缓存。 21 | 22 | // pthread_cond_t cond=PTHREAD_COND_INITIALIZER; // 声明并初始化条件变量。 23 | // pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER; // 声明并初始化互斥锁。 24 | sem_t notify,lock; // 声明信号量。 25 | 26 | void incache(int sig); // 生产者、数据入队。 27 | void *outcache(void *arg); // 消费者、数据出队线程的主函数。 28 | 29 | int main() 30 | { 31 | signal(15,incache); // 接收15的信号,调用生产者函数。 32 | 33 | sem_init(¬ify,0,0); // 初始化通知的信号量,第3个参数为0。 34 | sem_init(&lock,0,1); // 初始化加锁的信号量,第3个参数为1。 35 | 36 | // 创建三个消费者线程。 37 | pthread_t thid1,thid2,thid3; 38 | pthread_create(&thid1,NULL,outcache,NULL); 39 | pthread_create(&thid2,NULL,outcache,NULL); 40 | pthread_create(&thid3,NULL,outcache,NULL); 41 | 42 | pthread_join(thid1,NULL); 43 | pthread_join(thid2,NULL); 44 | pthread_join(thid3,NULL); 45 | 46 | sem_destroy(¬ify); 47 | sem_destroy(&lock); 48 | 49 | return 0; 50 | } 51 | 52 | void incache(int sig) // 生产者、数据入队。 53 | { 54 | static int mesgid=1; // 消息的计数器。 55 | 56 | struct st_message stmesg; // 消息内容。 57 | memset(&stmesg,0,sizeof(struct st_message)); 58 | 59 | // pthread_mutex_lock(&mutex); // 给缓存队列加锁。 60 | sem_wait(&lock); 61 | 62 | // 生产数据,放入缓存队列。 63 | stmesg.mesgid=mesgid++; vcache.push_back(stmesg); 64 | stmesg.mesgid=mesgid++; vcache.push_back(stmesg); 65 | stmesg.mesgid=mesgid++; vcache.push_back(stmesg); 66 | stmesg.mesgid=mesgid++; vcache.push_back(stmesg); 67 | 68 | // pthread_mutex_unlock(&mutex); // 给缓存队列解锁。 69 | sem_post(&lock); 70 | 71 | // pthread_cond_signal(&cond); // 发送条件信号,激活一个线程。 72 | // pthread_cond_broadcast(&cond); // 发送条件信号,激活全部的线程。 73 | 74 | sem_post(¬ify); // 把信号量的值加1,将唤醒消费者线程。 75 | sem_post(¬ify); // 把信号量的值加1,将唤醒消费者线程。 76 | sem_post(¬ify); // 把信号量的值加1,将唤醒消费者线程。 77 | sem_post(¬ify); // 把信号量的值加1,将唤醒消费者线程。 78 | } 79 | 80 | void *outcache(void *arg) // 消费者、数据出队线程的主函数。 81 | { 82 | struct st_message stmesg; // 用于存放出队的消息。 83 | 84 | while (true) 85 | { 86 | sem_wait(&lock); // 给缓存队列加锁。 87 | 88 | // 如果缓存队列为空,等待,用while防止虚假唤醒。 89 | while (vcache.size()==0) 90 | { 91 | // pthread_cond_wait(&cond,&mutex); 92 | 93 | sem_post(&lock); // 给缓存队列解锁。 94 | sem_wait(¬ify); // 等待信号量的值大于0。 95 | sem_wait(&lock); // 给缓存队列加锁。 96 | } 97 | 98 | // 从缓存队列中获取第一条记录,然后删除该记录。 99 | memcpy(&stmesg,&vcache[0],sizeof(struct st_message)); // 内存拷贝。 100 | vcache.erase(vcache.begin()); 101 | 102 | sem_post(&lock); // 给缓存队列解锁。 103 | 104 | // 以下是处理业务的代码。 105 | printf("phid=%ld,mesgid=%d\n",pthread_self(),stmesg.mesgid); 106 | usleep(100); 107 | } 108 | } 109 | 110 | -------------------------------------------------------------------------------- /public/demo/makefile: -------------------------------------------------------------------------------- 1 | all: demo1 demo2 demo4 demo5 demo7 demo8 demo10 demo12 demo16 demo18 demo20 demo21\ 2 | demo22 demo24 demo26 demo28 demo29 demo30 demo32 demo34 demo36 demo37 demo39 demo40\ 3 | demo42 demo43 demo45 demo47 demo48 demo50 demo51 demo52 4 | 5 | demo:demo.cpp 6 | g++ -Wall -g -o demo demo.cpp ../_public.cpp 7 | 8 | demo1:demo1.cpp 9 | g++ -Wall -g -o demo1 demo1.cpp ../_public.cpp 10 | 11 | demo2:demo2.cpp 12 | g++ -g -o demo2 demo2.cpp ../_public.cpp 13 | 14 | demo4:demo4.cpp 15 | g++ -g -o demo4 demo4.cpp ../_public.cpp 16 | 17 | demo5:demo5.cpp 18 | g++ -g -o demo5 demo5.cpp ../_public.cpp 19 | 20 | demo7:demo7.cpp 21 | g++ -g -o demo7 demo7.cpp ../_public.cpp 22 | 23 | demo8:demo8.cpp 24 | g++ -g -o demo8 demo8.cpp ../_public.cpp 25 | 26 | demo10:demo10.cpp 27 | g++ -g -o demo10 demo10.cpp ../_public.cpp 28 | 29 | demo12:demo12.cpp 30 | g++ -g -o demo12 demo12.cpp ../_public.cpp 31 | 32 | demo16:demo16.cpp 33 | g++ -g -o demo16 demo16.cpp ../_public.cpp 34 | 35 | demo18:demo18.cpp 36 | g++ -g -o demo18 demo18.cpp ../_public.cpp 37 | 38 | demo20:demo20.cpp 39 | g++ -g -o demo20 demo20.cpp ../_public.cpp 40 | 41 | demo21:demo21.cpp 42 | g++ -g -o demo21 demo21.cpp ../_public.cpp 43 | 44 | demo22:demo22.cpp 45 | g++ -g -o demo22 demo22.cpp ../_public.cpp 46 | 47 | demo24:demo24.cpp 48 | g++ -g -o demo24 demo24.cpp ../_public.cpp 49 | 50 | demo26:demo26.cpp 51 | g++ -g -o demo26 demo26.cpp ../_public.cpp 52 | 53 | demo28:demo28.cpp 54 | g++ -g -o demo28 demo28.cpp ../_public.cpp 55 | 56 | demo29:demo29.cpp 57 | g++ -g -o demo29 demo29.cpp ../_public.cpp 58 | 59 | demo30:demo30.cpp 60 | g++ -g -o demo30 demo30.cpp ../_public.cpp 61 | 62 | demo32:demo32.cpp 63 | g++ -g -o demo32 demo32.cpp ../_public.cpp 64 | 65 | demo34:demo34.cpp 66 | g++ -g -o demo34 demo34.cpp ../_public.cpp 67 | 68 | demo36:demo36.cpp 69 | g++ -g -o demo36 demo36.cpp ../_public.cpp 70 | 71 | demo37:demo37.cpp 72 | g++ -g -o demo37 demo37.cpp ../_public.cpp 73 | 74 | demo39:demo39.cpp 75 | g++ -g -o demo39 demo39.cpp ../_public.cpp 76 | 77 | demo40:demo40.cpp 78 | g++ -g -o demo40 demo40.cpp ../_public.cpp 79 | 80 | demo42:demo42.cpp 81 | g++ -g -o demo42 demo42.cpp ../_public.cpp 82 | 83 | demo43:demo43.cpp 84 | g++ -g -o demo43 demo43.cpp ../_public.cpp 85 | 86 | demo45:demo45.cpp 87 | g++ -g -o demo45 demo45.cpp ../_public.cpp 88 | 89 | demo47:demo47.cpp 90 | g++ -g -o demo47 demo47.cpp ../_public.cpp 91 | 92 | demo48:demo48.cpp 93 | g++ -g -o demo48 demo48.cpp ../_public.cpp -lpthread 94 | 95 | demo50:demo50.cpp 96 | cd .. && gcc -c -o libftp.a ftplib.c 97 | cd .. && gcc -fPIC -shared -o libftp.so ftplib.c 98 | g++ -g -o demo50 demo50.cpp ../_public.cpp ../_ftp.cpp ../libftp.a -lm -lc 99 | 100 | demo51:demo51.cpp 101 | g++ -g -o demo51 demo51.cpp ../_public.cpp ../_ftp.cpp ../libftp.a -lm -lc 102 | 103 | demo52:demo52.cpp 104 | g++ -g -o demo52 demo52.cpp ../_public.cpp ../_ftp.cpp ../libftp.a -lm -lc 105 | 106 | clean: 107 | rm -f demo1 demo2 demo4 demo5 demo7 demo8 demo10 demo12 demo16 demo18 demo20 demo21 108 | rm -f demo22 demo24 demo26 demo28 demo29 demo30 demo32 demo34 demo36 demo37 demo39 109 | rm -f demo40 demo42 demo43 demo45 demo47 demo48 demo50 demo51 demo52 110 | -------------------------------------------------------------------------------- /idc/c/obtmindtodb5.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * obtmindtodb.cpp,本程序用于把全国站点分钟观测数据入库到T_ZHOBTMIND表中,支持xml和csv两种文件格式。 3 | * 作者:吴从周。 4 | */ 5 | #include "idcapp.h" 6 | 7 | CLogFile logfile; 8 | 9 | connection conn; 10 | 11 | CPActive PActive; 12 | 13 | void EXIT(int sig); 14 | 15 | // 业务处理主函数。 16 | bool _obtmindtodb(char *pathname,char *connstr,char *charset); 17 | 18 | int main(int argc,char *argv[]) 19 | { 20 | // 帮助文档。 21 | if (argc!=5) 22 | { 23 | printf("\n"); 24 | printf("Using:./obtmindtodb pathname connstr charset logfile\n"); 25 | 26 | printf("Example:/project/tools1/bin/procctl 10 /project/idc1/bin/obtmindtodb /idcdata/surfdata \"127.0.0.1,root,mysqlpwd,mysql,3306\" utf8 /log/idc/obtmindtodb.log\n\n"); 27 | 28 | printf("本程序用于把全国站点分钟观测数据保存到数据库的T_ZHOBTMIND表中,数据只插入,不更新。\n"); 29 | printf("pathname 全国站点分钟观测数据文件存放的目录。\n"); 30 | printf("connstr 数据库连接参数:ip,username,password,dbname,port\n"); 31 | printf("charset 数据库的字符集。\n"); 32 | printf("logfile 本程序运行的日志文件名。\n"); 33 | printf("程序每10秒运行一次,由procctl调度。\n\n\n"); 34 | 35 | return -1; 36 | } 37 | 38 | // 关闭全部的信号和输入输出。 39 | // 设置信号,在shell状态下可用 "kill + 进程号" 正常终止些进程。 40 | // 但请不要用 "kill -9 +进程号" 强行终止。 41 | CloseIOAndSignal(); signal(SIGINT,EXIT); signal(SIGTERM,EXIT); 42 | 43 | // 打开日志文件。 44 | if (logfile.Open(argv[4],"a+")==false) 45 | { 46 | printf("打开日志文件失败(%s)。\n",argv[4]); return -1; 47 | } 48 | 49 | // PActive.AddPInfo(30,"obtmindtodb"); // 进程的心跳,30秒足够。 50 | // 注意,在调试程序的时候,可以启用类似以下的代码,防止超时。 51 | PActive.AddPInfo(5000,"obtmindtodb"); 52 | 53 | // 业务处理主函数。 54 | _obtmindtodb(argv[1],argv[2],argv[3]); 55 | 56 | return 0; 57 | } 58 | 59 | void EXIT(int sig) 60 | { 61 | logfile.Write("程序退出,sig=%d\n\n",sig); 62 | 63 | conn.disconnect(); 64 | 65 | exit(0); 66 | } 67 | 68 | // 业务处理主函数。 69 | bool _obtmindtodb(char *pathname,char *connstr,char *charset) 70 | { 71 | CDir Dir; 72 | 73 | // 打开目录。 74 | if (Dir.OpenDir(pathname,"*.xml")==false) 75 | { 76 | logfile.Write("Dir.OpenDir(%s) failed.\n",pathname); return false; 77 | } 78 | 79 | CFile File; 80 | 81 | CZHOBTMIND ZHOBTMIND(&conn,&logfile); 82 | 83 | int totalcount=0; // 文件的总记录数。 84 | int insertcount=0; // 成功插入记录数。 85 | CTimer Timer; // 计时器,记录每个数据文件的处理耗时。 86 | 87 | while (true) 88 | { 89 | // 读取目录,得到一个数据文件名。 90 | if (Dir.ReadDir()==false) break; 91 | 92 | // 连接数据库。 93 | if (conn.m_state==0) 94 | { 95 | if (conn.connecttodb(connstr,charset)!=0) 96 | { 97 | logfile.Write("connect database(%s) failed.\n%s\n",connstr,conn.m_cda.message); return -1; 98 | } 99 | 100 | logfile.Write("connect database(%s) ok.\n",connstr); 101 | } 102 | 103 | totalcount=insertcount=0; 104 | 105 | // 打开文件。 106 | if (File.Open(Dir.m_FullFileName,"r")==false) 107 | { 108 | logfile.Write("File.Open(%s) failed.\n",Dir.m_FullFileName); return false; 109 | } 110 | 111 | char strBuffer[1001]; // 存放从文件中读取的一行。 112 | 113 | while (true) 114 | { 115 | if (File.FFGETS(strBuffer,1000,"")==false) break; 116 | 117 | // 处理文件中的每一行。 118 | totalcount++; 119 | 120 | ZHOBTMIND.SplitBuffer(strBuffer); 121 | 122 | if (ZHOBTMIND.InsertTable()==true) insertcount++; 123 | } 124 | 125 | // 删除文件、提交事务。 126 | // File.CloseAndRemove(); 127 | 128 | conn.commit(); 129 | 130 | logfile.Write("已处理文件%s(totalcount=%d,insertcount=%d),耗时%.2f秒。\n",Dir.m_FullFileName,totalcount,insertcount,Timer.Elapsed()); 131 | } 132 | 133 | return true; 134 | } 135 | 136 | 137 | 138 | 139 | -------------------------------------------------------------------------------- /public/socket/demo20.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 程序名:demo20.cpp,此程序演示采用开发框架的CTcpServer类实现socket通讯多线程的服务端。 3 | * 作者:吴从周 4 | */ 5 | #include "../_public.h" 6 | 7 | CLogFile logfile; // 服务程序的运行日志。 8 | CTcpServer TcpServer; // 创建服务端对象。 9 | 10 | void EXIT(int sig); // 进程的退出函数。 11 | 12 | pthread_spinlock_t vthidlock; // 用于锁定vthid的自旋锁。 13 | vector vthid; // 存放全部线程id的容器。 14 | void *thmain(void *arg); // 线程主函数。 15 | 16 | void thcleanup(void *arg); // 线程清理函数。 17 | 18 | int main(int argc,char *argv[]) 19 | { 20 | if (argc!=3) 21 | { 22 | printf("Using:./demo20 port logfile\nExample:./demo20 5005 /tmp/demo20.log\n\n"); return -1; 23 | } 24 | 25 | // 关闭全部的信号和输入输出。 26 | // 设置信号,在shell状态下可用 "kill + 进程号" 正常终止些进程 27 | // 但请不要用 "kill -9 +进程号" 强行终止 28 | CloseIOAndSignal(); signal(SIGINT,EXIT); signal(SIGTERM,EXIT); 29 | 30 | if (logfile.Open(argv[2],"a+")==false) { printf("logfile.Open(%s) failed.\n",argv[2]); return -1; } 31 | 32 | // 服务端初始化。 33 | if (TcpServer.InitServer(atoi(argv[1]))==false) 34 | { 35 | logfile.Write("TcpServer.InitServer(%s) failed.\n",argv[1]); return -1; 36 | } 37 | 38 | pthread_spin_init(&vthidlock,0); 39 | 40 | while (true) 41 | { 42 | // 等待客户端的连接请求。 43 | if (TcpServer.Accept()==false) 44 | { 45 | logfile.Write("TcpServer.Accept() failed.\n"); EXIT(-1); 46 | } 47 | 48 | logfile.Write("客户端(%s)已连接。\n",TcpServer.GetIP()); 49 | 50 | // 创建一个新的线程,让它与客户端通讯。 51 | pthread_t thid; 52 | if (pthread_create(&thid,NULL,thmain,(void *)(long)TcpServer.m_connfd)!=0) 53 | { 54 | logfile.Write("pthread_create() failed.\n"); TcpServer.CloseListen(); continue; 55 | } 56 | 57 | pthread_spin_lock(&vthidlock); 58 | vthid.push_back(thid); // 把线程id放入容器。 59 | pthread_spin_unlock(&vthidlock); 60 | } 61 | } 62 | 63 | void *thmain(void *arg) // 线程主函数。 64 | { 65 | pthread_cleanup_push(thcleanup,arg); // 把线程清理函数入栈(关闭客户端的socket)。 66 | 67 | int connfd=(int)(long)arg; // 客户端的socket。 68 | 69 | pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,NULL); // 线程取消方式为立即取消。 70 | 71 | pthread_detach(pthread_self()); // 把线程分离出去。 72 | 73 | // 子线程与客户端进行通讯,处理业务。 74 | int ibuflen; 75 | char buffer[102400]; 76 | 77 | // 与客户端通讯,接收客户端发过来的报文后,回复ok。 78 | while (1) 79 | { 80 | memset(buffer,0,sizeof(buffer)); 81 | if (TcpRead(connfd,buffer,&ibuflen,30)==false) break; // 接收客户端的请求报文。 82 | logfile.Write("接收:%s\n",buffer); 83 | 84 | strcpy(buffer,"ok"); 85 | if (TcpWrite(connfd,buffer)==false) break; // 向客户端发送响应结果。 86 | logfile.Write("发送:%s\n",buffer); 87 | } 88 | 89 | close(connfd); // 关闭客户端的连接。 90 | 91 | // 把本线程id从存放线程id的容器中删除。 92 | pthread_spin_lock(&vthidlock); 93 | for (int ii=0;ii 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | using namespace std; 11 | 12 | // 缓存队列消息的结构体。 13 | struct st_message 14 | { 15 | int mesgid; // 消息的id。 16 | char message[1024]; // 消息的内容。 17 | }stmesg; 18 | 19 | vector vcache; // 用vector容器做缓存。 20 | 21 | pthread_cond_t cond=PTHREAD_COND_INITIALIZER; // 声明并初始化条件变量。 22 | pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER; // 声明并初始化互斥锁。 23 | 24 | void incache(int sig); // 生产者、数据入队。 25 | void *outcache(void *arg); // 消费者、数据出队线程的主函数。 26 | 27 | int main() 28 | { 29 | signal(15,incache); // 接收15的信号,调用生产者函数。 30 | 31 | // 创建三个消费者线程。 32 | pthread_t thid1,thid2,thid3; 33 | pthread_create(&thid1,NULL,outcache,NULL); 34 | pthread_create(&thid2,NULL,outcache,NULL); 35 | pthread_create(&thid3,NULL,outcache,NULL); 36 | 37 | pthread_join(thid1,NULL); 38 | pthread_join(thid2,NULL); 39 | pthread_join(thid3,NULL); 40 | 41 | pthread_cond_destroy(&cond); 42 | pthread_mutex_destroy(&mutex); 43 | 44 | return 0; 45 | } 46 | 47 | void incache(int sig) // 生产者、数据入队。 48 | { 49 | static int mesgid=1; // 消息的计数器。 50 | 51 | struct st_message stmesg; // 消息内容。 52 | memset(&stmesg,0,sizeof(struct st_message)); 53 | 54 | pthread_mutex_lock(&mutex); // 给缓存队列加锁。 55 | 56 | // 生产数据,放入缓存队列。 57 | stmesg.mesgid=mesgid++; vcache.push_back(stmesg); 58 | stmesg.mesgid=mesgid++; vcache.push_back(stmesg); 59 | stmesg.mesgid=mesgid++; vcache.push_back(stmesg); 60 | stmesg.mesgid=mesgid++; vcache.push_back(stmesg); 61 | 62 | pthread_mutex_unlock(&mutex); // 给缓存队列解锁。 63 | 64 | //pthread_cond_signal(&cond); // 发送条件信号,激活一个线程。 65 | pthread_cond_broadcast(&cond); // 发送条件信号,激活全部的线程。 66 | } 67 | 68 | void thcleanup(void *arg) 69 | { 70 | // 在这里释放关闭文件、断开网络连接、回滚数据库事务、释放锁等等。 71 | printf("cleanup ok.\n"); 72 | 73 | pthread_mutex_unlock(&mutex); 74 | 75 | /* 76 | A condition wait (whether timed or not) is a cancellation point. When the cancelability type of a thread is set to PTHREAD_CAN_CEL_DEFERRED, a side-effect of acting upon a cancellation request while in a condition wait is that the mutex is (in effect) re-acquired before calling the first cancellation cleanup handler. The effect is as if the thread were unblocked, allowed to execute up to the point of returning from the call to pthread_cond_timedwait() or pthread_cond_wait(), but at that point notices the cancellation request and instead of returning to the caller of pthread_cond_timedwait() or pthread_cond_wait(), starts the thread cancellation activities, which includes calling cancellation cleanup handlers. 77 | 意思就是在pthread_cond_wait时执行pthread_cancel后, 78 | 要先在线程清理函数中要先解锁已与相应条件变量绑定的mutex, 79 | 这样是为了保证pthread_cond_wait可以返回到调用线程。 80 | */ 81 | }; 82 | 83 | void *outcache(void *arg) // 消费者、数据出队线程的主函数。 84 | { 85 | pthread_cleanup_push(thcleanup,NULL); // 把线程清理函数入栈。 86 | 87 | struct st_message stmesg; // 用于存放出队的消息。 88 | 89 | while (true) 90 | { 91 | pthread_mutex_lock(&mutex); // 给缓存队列加锁。 92 | 93 | // 如果缓存队列为空,等待,用while防止条件变量虚假唤醒。 94 | while (vcache.size()==0) 95 | { 96 | pthread_cond_wait(&cond,&mutex); 97 | } 98 | 99 | // 从缓存队列中获取第一条记录,然后删除该记录。 100 | memcpy(&stmesg,&vcache[0],sizeof(struct st_message)); // 内存拷贝。 101 | vcache.erase(vcache.begin()); 102 | 103 | pthread_mutex_unlock(&mutex); // 给缓存队列解锁。 104 | 105 | // 以下是处理业务的代码。 106 | printf("phid=%ld,mesgid=%d\n",pthread_self(),stmesg.mesgid); 107 | usleep(100); 108 | } 109 | 110 | pthread_cleanup_pop(1); // 把线程清理函数出栈。 111 | } 112 | 113 | -------------------------------------------------------------------------------- /public/socket/tcpepoll.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 程序名:tcpepoll.cpp,此程序用于演示采用epoll模型的使用方法。 3 | * 作者:吴从周 4 | */ 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include /* See NOTES */ 12 | #include 13 | #include 14 | #include 15 | 16 | // 初始化服务端的监听端口。 17 | int initserver(int port); 18 | 19 | int main(int argc,char *argv[]) 20 | { 21 | if (argc != 2) { printf("usage: ./tcpepoll port\n"); return -1; } 22 | 23 | // 初始化服务端用于监听的socket。 24 | int listensock = initserver(atoi(argv[1])); 25 | printf("listensock=%d\n",listensock); 26 | 27 | if (listensock < 0) { printf("initserver() failed.\n"); return -1; } 28 | 29 | // 创建epoll句柄。 30 | int epollfd=epoll_create(1); 31 | 32 | // 为监听的socket准备可读事件。 33 | struct epoll_event ev; // 声明事件的数据结构。 34 | ev.events=EPOLLIN; // 读事件。 35 | ev.data.fd=listensock; // 指定事件的自定义数据,会随着epoll_wait()返回的事件一并返回。 36 | 37 | // 把监听的socket的事件加入epollfd中。 38 | epoll_ctl(epollfd,EPOLL_CTL_ADD,listensock,&ev); 39 | 40 | struct epoll_event evs[10]; // 存放epoll返回的事件。 41 | 42 | while (true) 43 | { 44 | // 等待监视的socket有事件发生。 45 | int infds=epoll_wait(epollfd,evs,10,-1); 46 | 47 | // 返回失败。 48 | if (infds < 0) 49 | { 50 | perror("epoll() failed"); break; 51 | } 52 | 53 | // 超时。 54 | if (infds == 0) 55 | { 56 | printf("epoll() timeout.\n"); continue; 57 | } 58 | 59 | // 如果infds>0,表示有事件发生的socket的数量。 60 | // 遍历epoll返回的已发生事件的数组evs。 61 | for (int ii=0;ii")==false) break; 122 | } 123 | else 124 | { 125 | if (File.Fgets(strBuffer,1000,true)==false) break; 126 | if (strstr(strBuffer,"站点")!=0) continue; // 把csv文件中的第一行扔掉。 127 | } 128 | 129 | // 处理文件中的每一行。 130 | totalcount++; 131 | 132 | ZHOBTMIND.SplitBuffer(strBuffer,bisxml); 133 | 134 | if (ZHOBTMIND.InsertTable()==true) insertcount++; 135 | } 136 | 137 | // 删除文件、提交事务。 138 | File.CloseAndRemove(); 139 | 140 | conn.commit(); 141 | 142 | logfile.Write("已处理文件%s(totalcount=%d,insertcount=%d),耗时%.2f秒。\n",Dir.m_FullFileName,totalcount,insertcount,Timer.Elapsed()); 143 | } 144 | 145 | return true; 146 | } 147 | 148 | 149 | 150 | 151 | --------------------------------------------------------------------------------