看完Neil和Richard的《Linux程序设计》,根据书中的例子,自己写了一个简化版的CD管理应用程序。
主要用到了几个在书中讲到的知识点:
1.采用C/S模式,在同一机子上运行;
2.用curses作为客户端显示接口;
3.数据用MySQL存储;
4.进程间通讯使用命名管道。
写完下来总共900行左右的代码吧,断断续续不知道写了多久,感受还是挺深刻的,中途出了很多问题,也有很多地方理解不够深刻,甚至一度对自己的C++语法掌握程度产生了怀疑,哎,的确要去补一补Primer了。
应用程序与书上的例程有挺大出入的,全程基本没有照书看。
1.CD保存的信息只有CD名与CD中的歌曲,歌曲也只保存歌曲名,一个CD中能有多个歌曲;
2.客户端负责做人机接口,发送和接受数据包,与服务端通讯;
其功能有增加CD,修改CD(即修改CD中的歌曲),列出所有的CD和曲目,删除CD,找CD。
3.服务端负责接受和处理客户端发来的数据包,处理后发回给客户端,数据的存储和查找通过MySQL处理。
MySQL的处理命令可以参考另一篇博文,还是很方便的,比Linux自带的数据库好用多了。
CDrecord库里有两个表分别是CDs和tracks
结构如下:
4.客户端与服务端的通讯使用管道,
管道发送的struct结构如下:
struct data_package { pid_t pid_client; char data[MAX_STRING]; cmd_list cmd; int res; };
其中cmd_list定义了客户端需要执行何种命令:typedef enum { add_CD = 0, get_CDname, find_CD, remove_CD, update_CD, count_CD, add_TRACKS, get_CDnum, } cmd_list;
客户端都发送到同一个管道给服务端而服务端根据根据客户端不同的pid将处理后的信息返回到客户端int send (cmd_list send_cmd, char* send_string, pid_t send_pid, int send_res) { data_package data_to_send; data_to_send.pid_client = send_pid; sprintf (data_to_send.data, "%s", send_string); data_to_send.cmd = send_cmd; data_to_send.res = send_res; //open the pipe char *pipe_name = new char[MAX_STRING]; sprintf (pipe_name, CLIENT_FIFO_NAME, send_pid); if ((client_fd = open (pipe_name, O_RDWR)) == -1) printf ("client fifo %d open failed\n", (int) send_pid); //send the data write (client_fd, &data_to_send, sizeof (data_to_send)); //close the pipe close (client_fd); return 0; }
整个程序写下来,几个要注意的地方:
1. 还是C风格的字符串问题,包括申请空间,string的转换,取子串,参数传递等等问题,在写之前没想到自己在这方面这么抓急,不过也算是搞懂了。
这里还有一个问题,就是如果在struct里面成员有string类的话,传递是会发生core dump的,好像是因为Linux里面默认的是使用C编译器导致的。
2.第一次写C/S应用程序,从架构到每一个细节都是自己决定自己想,先确定好接口真的很重要。
把代码放在CSDN上了,有兴趣欢迎下载
https://code.csdn.net/d521000121/cdrecord/releases/tag/1.0