admin 管理员组

文章数量: 1087139


2024年12月26日发(作者:fonts文件夹怎么恢复)

一种远程管理Linux系统工具的设计与实现

摘 要

现在,Linux已经是应用比较广泛的操作系统之一,在其系统中有很多的服

务。为了实现远程配置和管理Linux中的各种服务,需要有一种远程管理Linux

系统的工具软件,Webmin就是一种较好的B/S模式软件,而该课题以C/S模式

实现。该工具主要功能实现对Linux系统用户和组的添加、修改和删除;对系

统应用服务(如:DNS、FTP、Apache、系统启动服务管理)进行管理和配置,这

些服务的远程配置主要是通过修改服务配置文本文件来实现的。该远程管理工

具选用C/S模式设计,在客户端,采用GTK编程来实现操作界面;在服务器

端,选用Linux系统的文件调用函数来读写配置文件中的数据;采用Sock TCP

编程来实现客户端和服务端之间的数据通信。通过系统测试后,完成预期的目

标,但是需要进一步完善程序和考虑安全性后,方可应用于实际的远程管理。

关键词

:Linux;系统服务;C/C++;GTK;系统调用;Socket

The Design and

Implementation of a Remote Management

Tool for Linux

Abstract

The operating system of Linux has become one of the most popular operating

systems nowadays. It provides many kinds of service. In order to configure and

manage the service remotely, the tool of remote management of the operating

system of Linux is needed. Webmin is a good tool of software based on the model of

B/S. This design is implemented based on the model of C/S. The main functions of

the system include addition, modification, deletion of users and groups of Linux

operating system and configuration and management of the service of application of

the system, such as the DNS, FTP, Apache and the management of booting service.

The remote management of service is implemented by modifying the files of

configuration. The model of C/S is selected by this system. In the Client, the

operating interface is made by the programming of GTK. In the Server, the functions

of transferring of files of Linux operating system are used to write and read the data

of the configuration files. The communication of Client and Server is implemented

by the programming of Sock TCP. The testing demonstrates that the system has

reached the prospective goal. But lots of improvements should be made and the

problems of security should be considered more. After being modified and perfected,

the system can be used to manage the system remotely.

Key words:

Linux;System Servers;C/C++;GTK;System Call;Socket

目 录

论文总页数:33页

1 引言 ......................................................................................................................................... 1

1.1

1.2

1.3

1.4

2

课题背景 ........................................................................................................................ 1

国内外研究现状 ............................................................................................................ 1

本课题研究的意义 ........................................................................................................ 1

本课题的研究方法 ........................................................................................................ 1

GTK编程 ................................................................................................................................ 1

2.1

2.2

GTK简介 ......................................................................................................................... 1

常用的GTK构件 ............................................................................................................ 3

3 LINUX系统调用 .................................................................................................................... 6

3.1

3.2

3.3

L

INUX

系统文件 ............................................................................................................... 6

如何从文件中读取数据................................................................................................. 6

进程和线程的使用 ........................................................................................................ 7

4 基本的套接口编程.................................................................................................................. 7

4.1

4.2

概述 ................................................................................................................................ 7

简单的网络编程 ............................................................................................................ 8

5 程序设计和流程图................................................................................................................ 10

5.1

5.2

设计思路 ...................................................................................................................... 10

服务程序 ...................................................................................................................... 10

5.2.1 流程设计 ................................................................................................................. 10

5.2.2 功能模块 ................................................................................................................. 11

5.3 客户程序 ...................................................................................................................... 20

5.3.1 设计思路 ................................................................................................................. 20

5.3.2 程序设计 ................................................................................................................. 20

6 系统测试 ............................................................................................................................... 30

结 论 ......................................................................................................................................... 32

参考文献 ......................................................................................................................................... 33

致 谢 ......................................................................................................................................... 34

声 明 ............................................................................................................错误!未定义书签。

1 引言

1.1 课题背景

Linux是目前应用最广泛的操作系统之一,基于Linux系统的网络服务软

件(如FTP、Apache、DNS、SendMail)的功能也很强大。但是现在能够统一对

这些服务进行管理的软件却很少的。本课题为减轻系统管理员的工作量而提供

了一些简单的系统服务的管理和查看工具。

1.2 国内外研究现状

Linux是现在开源项目的代表,很多大的硬件厂商也在支持Linux的发展。

而且Linux平台上的服务软件也是越来越多了。现在Linux已经进入到企业级

应用,Webmin是一种基于B/S模式的远程管理Linux系统的软件工具。

1.3 本课题研究的意义

本课题是为了给系统管理员提供一种远程管理Linux中某些主要服务的工

具软件,完成服务配置管理和查看一些重要的数据。由于Linux是开源项目的

代表,对Linux的学习有助于对计算机系统和软件理论知识的提高。通过该课

题的设计和实现,既解决远程管理Linux系统,又让自己掌握了一些Linux系

统编程和Sock编程能力。

1.4 本课题的研究方法

本课题主要是对网络配置、GTK库、Linux系统调用和网络编程方面的研究。

采用C/S模式,在客户端采用GTK函数实现用户界面的编写,在服务器端通过

Linux的系统调用,来实现本地服务配置,然后再通过Sock编程来实现服务器

和客户端的通信,传递配置内容和服务指令。

2 GTK编程

2.1 GTK简介

GTK(GIMP Toolkit,GIMP工具包)是一个用于创造图形用户接口的多平台工

具。它包含有基本的空间和一些很复杂的控件:例如文件选择控件。GTK最初

是GIMP(GNU图形处理程序)开发的控件集合,然后它不断扩展,直到今天被用

于大量的应用程序当中。

从根本上来说,主循环是由glib实现的。Gtk将glib主循环连接到Gdk

的X服务器,并提供一个方便的接口。

Gtk分别用gtk_main()函数和gtk_main_quit()函数来运行主循环和退出

主循环,当系统调用了gtk_main()函数后,由于gtk_main()函数可以递归调用,

所以需要调用gtk_main_quit()函数才能退出gtk。

gtk_main()函数的所有功能都是监视Gtk程序和与X服务的连接,对同样

的时间队列起作用。gtk_main()函数用于阻塞该进程直到满足某些条件。所有

的Gtk程序都用这个技巧使应用程序正在运行时main()函数被阻塞,直到用户

通过点击鼠标或键盘来产生一个信号,并通过该信号来调用相应的回调函数。

GTK是一个时间驱动工具包,它将在gtk_main()函数中一直等待,直到某

个事件的发生或控制权被交给相应的函数。

(1) 信号

控制权的传递是使用“信号”的方法。一旦事件发生,比如鼠标器按钮被

按下,被按下的构件(按钮)将引发适当的信号。有一些信号是大多数构件都

具备的,比如destory,还有一些是某些构件专有的,比如在按扭的toggled

信号。要让一个按钮执行一个操作,我们需要写一段信号处理程序,以捕获它

的信号,然后调用相应的回调函数。

这由类似以下所示的函数实现:

Gint gtk_signal_connect(GtkObject *object,

Gchar *name,

GtkSignalFunc func,

gpointer func_data );

上面函数的第3个参数为回调函数,它的形式通常是:

void callback_func( GtkWidget *widget, gpointer callback_data );

(2) 事件

除了上面的信号机制外,还有一些和X事件机制相对应的事件。回调函数也

可以和这些事件连接起来应用。将回调函数连接到X的某一个事件,需要使用

gtk_signal_connect函数,并使用事件名称作为命名参数。事件的回调函数与信

号的回调函数在形式上略有不同:

Void func(GtkWidget *widget,

GdkEvent *event,

gpointer callback_data );

GdkEvent是C中的联合体结构,其类型依赖于发生的事件。要想知道哪一个

事件已经引发,可以查看类型参数,因为每个可能的可选事件都有一个反映引发

事件的类型参数。将回调函数与一个事件连接起来,需要使用以下形式的函数:

gtk_signal_connect( GTK_OBJECT(button),

"button_press_event"

GTK_SIGNAL_FUNC(button_press_callback),

NULL) ;

这里假定button是一个按钮构件。现在,当鼠标移动到按钮上方,鼠标按钮

按下时,将调用button_press_callback函数。回调函数可以作如下声明:

static gintbutton_press_callback( GtkWidget *widget,

GdkEventButton *event,

gpointer data);

2.2 常用的GTK构件

GTK构件可以分为两种。一种有一个相关联的GdkWindow窗口,另一种没有。

绝大多数构件都是第一种构件,并且可以显示在GdkWindow窗口。

(1) GtkWindow构件

GtkWindow构件是最大的容器,它实际就是一个窗体构件。但是它只可以容

纳一个子构件,所以要让GtkWindow能容纳更多的构件必须使用布局控件来布局。

用下面的函数创建新窗口:

GtkWidget* gtk_window_new (GtkWindowType type);

用下面的构件向窗口中添加子构件:

gtk_container_add (GTK_CONTAINER (window), widget);

(2) 组装构件

组装构件通常是直接从GtkContainer派生而来。这些构件可以有多个子构

件,它们的作用就是管理布局。“管理布局”意味着这些容器为它们容纳的子构

件分配大小尺寸和位置。例如,GtkVBox将它的子构件在一个垂直的栈内排列。

GtkTable构件可以让构件在一个表格上根据单元格定位。

GtkTable(表格构件)是很常用的用于定位的构件。我们用表格构件创建一个

网格,把构件放在网格里。构件可以在网格中占据任意多个格子。

用gtk_table_new创建一个表格构件:

GtkWidget *gtk_table_new( gint rows,gint columns,gint homogeneous);

要将构件放到表格中,可以使用下列函数:

void gtk_table_attach(GtkTable *table,

GtkWidget *child,

gint left_attach,

gint right_attach,

gint top_attach,

gint bottom_attach,

gint x options,

gint yoptions,

gint xpadding,gint ypadding );

(3) 按钮构件

GtkButton(普通按钮构件)是应用程序中使用最广泛的构件。它一般用于当

用户点击它时执行某个动作,其使用和创建也相当简单。

可以用gtk_button_new_with_label()创建带标题的按钮。按钮创建以后就

可以用上面所讲述的GTK信号和回调函数或事件机制来实现,当按扭按下或有其

他操作时候的回调函数来响应相应的函数或事件。

(4) 文本构件

GtkText(文本构件)允许多行显示或编辑文本。它支持多种颜色以及多种

字体的文本,允许它们以任何需要的形式混合显示,还有许多与Emacs兼容的文

本编辑命令。文本构件支持完全的剪切/粘贴功能,还包括双击选择一个单词和

单击选择整行的功能。

创建新Text构件只有一个函数:

GtkWidget *gtk_text_new( GtkAdjustment *hadj,GtkAdjustment *vadj );

文本构件有两个主要用途:允许用户编辑一段文本,或向用户显示多行文本。

为了在两种操作模式之间进行切换,文本构件有以下函数:

void gtk_text_set_editable( GtkText *text,gint editable );

为了在当前插入点插入文本,可以使用gtk_text_insert函数。插入时可以

指定文本的背景色、前景色和字体。

void gtk_text_insert(GtkText *text,

GdkFont *font,

GdkColor *fore,

GdkColor *back,

const char *chars,

gint length );

(5) 标签构件

GtkLabel(标签构件)是GTK中最常用的构件之一,实际上它很简单。因为没

有相关联的X窗口,标签构件不能引发信号。如果需要引发信号,可以将它放在

一个事件盒构件中,或放在按钮构件中。用以下函数创建新标签构件:

GtkWidget *gtk_label_new(char *str );

唯一的参数是要由标签显示字符串。创建标签构件后,要改变标签内的文本,

用以下函数:

void gtk_label_set_text( GtkLabel *lacbel,char *str );

第一参数是前面创建的标签构件(用GTK_LABEL()宏转换),第二个参数是新

字符串。如果需要,新字符串所需的空间会做自动调整。在字符串中放置换行符,

可以创建多行标签。

(6) 笔记本构件

GtkNotebook(笔记本构件)是互相重叠的页面集合,每一页都包含不同的信

息,且一次只有一个页面是可见的。该构件在GUI(图形用户接口)编程中很常用。

要说明大量的相关信息,同时把它们分别显示时,使用这种构件是一个很好的方

法。许多应用程序的“选项”对话框都使用了这个构件。用下面的函数可以创建

新笔记本构件。

GtkWidget *gtk_notebook_new( void );

向笔记本构件中添加页面,主要有两种方法,而且非常相似的,如下:

 在笔记本构件中追加页面:

void gtk_notebook_append_page(GtkNotebook *notebook,

GtkWidget *child,

GtkWidget *tab_label );

 在笔记本构件中前插页面:

void gtk_notebook_prepend_page(GtkNotebook *notebook,

GtkWidget *child,

GtkWidget *tab_label );

其中child参数是放在笔记本构件上的子构件,tab_label是要添加的页面的

标签。子构件必须分别创建,一般是一个容器构件,比如说表格构件。

(7) 分栏列表构件

GtkCList(分栏列表构件)是GtkList(列表构件)的替代品,但它提供更多的

特性。分栏列表构件是多列列表构件,它有能力处理数千行的信息。每一列都可

以有一个标题,而且可以是活动的,还可以将函数绑定到列选择上。

创建GtkClist构件的方法和创建其他构件的方法类似。因为GtkCList可以有

多列,因而在创建它之前,必须确定要创建的列表的列数。创建分栏列表的函数:

GtkWidget *gtk_clist_new ( gint columns );

GtkWidget *gtk_clist_new_with_titles(gint columns,

gchar *titles[] );

创建列表后,需要向构件中添加一些要显示和操作的数据,用下面的函数可

以向列表中添加一些数据行:

gint gtk_clist_prepend( GtkCList *clist,gchar *text[] );

gint gtk_clist_append( GtkCList *clist,gchar *text[] );

用下面的函数可以删除一些数据行:

void gtk_clist_remove( GtkCList *clist,gint row );

与其他构件一样,GtkCList有一些信号供我们使用。GtkCList构件是从容器

构件GtkContainer派生的,它有容器所具有的一些信号,还有下面这些附加信号:

select_row:选中一行时引发,该信号传递信息,依次是GtkCList *clist、

gint row、gint column、GtkEventButton *event。

unselect_row:用户对一行取消选择,引发这个信号。传递的信息与上一个

信号一样。

click_column:选中某一列时引发,传递信息,依次是: GtkCList *clist、

gint column。所以,要将一个回调函数连接到select_row信号上,回调函数应

该像下面这样:

void select_row_callback(GtkWidget *widget,gint row,gint column,

GdkEventButton *event,gpointer data);

回调函数用下面的形式连接到信号:

gtk_signal_connect(GTK_OBJECT( clist),

"select_row",

GTK_SIGNAL_FUNC(select_row_callback),

NULL);

以上只是简单介绍了本课题在客户端界面编写的时候可用到的GTK库函数,

但实际的GTK比上面的操作还要复杂得多。

3 Linux系统调用

3.1 Linux系统文件

在Linux中最主要的资源就是文件,很多设备都是以文件形式存在的,所

以大多数输入/输出都要通过文件读写来实现。也就是说通过一个单一的接口就

可以处理外围设备和程序之间的通信。Linux文件类型常见的有:普通文件、

目录、字符设备文件、块设备文件、符号链接文件等。很多系统服务和应用服

务的配置文件都是以普通文件的形式存在,这些文件很容易通过Linux的系统

调用来配置和修改,也可以用文档文件的修改方式来修改。

3.2 如何从文件中读取数据

Linux文件读取有两种方法:一种是通过C语言的标准库函数调用来完成;

另一种是通过对Linux的系统调用来完成。文件读取分3步完成:第一步是打

开要读取的文件;第二步是把文件读取到内存中去;第三步是关闭打开的文件。

 在Linux中打开一个文件可以通过系统调用open()函数来实现:

int fd = open(char *name,int how);

其中参数name是要打开的函数名字;how是打开的方式;返回值-1为错误,

成功就返回一个文件描述符。

 Linux系统读取文件内容通过系统调用read()函数来实现,函数原形:

ssize_t numread = read(int fd,void *buff,size_t qty);

第1个参数是打开的文件描述符,第2个参数是存储文件数据的内存地址,

第3个参数是读取数据大小。如果读取成功返回值是读取的字节数,失败就返

回-1。

 系统调用write()函数将内存中的数据写入到文件中去,函数原形:

ssize_t resut = write(int fd,void *buff,zize_t amt);

这个系统将调用buff的数据写到文件中。第1个参数是打开的文件描述符;

第2个参数是要写入文件数据的内存地址;第3个参数是写入文件的大小。

进程不需要再对文件进行读写操作时,就要关系文件打开的文件。close()

能关闭打开的文件,其函数原形:

int result = close(int fd);

这个系统调用会关闭进程和文件之间的连接。参数是打开的文件描述符号。

关闭成功返回0,失败返回-1。

3.3 进程和线程的使用

(1) Linux进程

Linux进程创建很特别。很多其他操作都提供了产生进程的机制,在新的

进程空间中创建进程,读取可执行文件。但是Linux不同,它创建的子进程具

有和父进程相同的数据、代码段。父进程和子进程间的区别就是进程的pid不

同,其他的都一样:

pid_t result = fork(void)

该函数比较特殊,它返回两次函数值,一次返回值是向父进程返回子进程

的PID。还有一次是返回0(子进程)。

在使用fork()函数创建进程的时候经常父进程等待子进程结束。系统调用

wait(&status)让父进程阻塞直到子进程结束:

pid_t result = wait(&status);

(2) Linux线程

进程为线程提供了运行环境,多个函数可以同时运行,但是他们都是运行

在相同的进程中的。pthread_cearte()函数可以创建一个线程:

int pthread_ceate(pthread_t *thread,

pthread_attr_t *attr,

void *(*func)(void*),

void *arg);

4 基本的套接口编程

4.1 概述

让同一网络的不同计算机的进程能够相互通信,首先要确定这些程序如何

进行通信。本课题所用的协议是TCP/IP协议。如果客户和服务器处于同一以太

网,如图1所示。

客户应用程序

TCP

IP

以太网驱动

应用层协议

服务器应用程序

TCP协议

TCP

IP协议

IP

以太网协议

以太网驱动

图1 网络示意图

4.2 简单的网络编程

(1) socket函数

socket函数功能是创建一个套接口描述符,并且指定希望的通信协议(使

用IPV4的TCP,或者使用IPV6的UPD等)。

int socket(int family,int type,int protocol);

其中family参数指明协议族,type参数指明套接口类型,protocol参数

为某个协议的常数。函数调用成功时候返回一个非负的描述符。

(2) connect函数

TCP客户程序用connect函数来发起和TCP服务程序的连接。这个函数通

常是在客户程序中使用。

int connect(int sockfd,

const sgruct sockaddr *servaddr,

socklen_t addrlen);

sockfd是有socket函数返回的一个套接口描述符,第2个和第3个参数

分别是一个指向套接口地址结构指针和结构的大小。当函数调用成功的时候返

回0,出错就返回-1。

(3) bind函数

该函数是把一个本地协议地址赋予一个套接口,对于网际协议,协议地址

是一个32位的IPV4地址和一个16位的TCP端口号的组合。

int bind(int sockfd,const struct aockaddr *myadd,socklen_t

addrlen);

第2个参数是一个指向特定协议的地址结构的指针,第3个参数是该地址

结构的长度。调用成功返回0,错误返回-1。

(4) listen函数

listen函数只能由TCP服务器调用,他完成两件事:

一是当socket函数创建一个套接口时它是一个主动的套接口,该函数就是

把它转换成一个被动的套接口

二是该函数规定了为相应套接口排队的最大的连接个数。

int listen(int sockfd,int backlog);

本函数通常都是在调用socket和bind这两个函数之后。

(5) accept函数

int accept(int sockfd,struct sockaddr *cliaddr,socklen_t

*addrlen);

参数cliaddr和addrlen用来返回已经连接的客户端的协议地址。函数返

回值为一个非负的描述符表示成功,出错为-1。

这里需要指出的是参数的描述符为监听套接口,就是在等待连接的时候还

没有建立连接的套接口,而返回值是连接的新的套接口。也就是能和客户端通

信的套接口。区分这两个东西是很重要的。

(6)close函数

套接口编程通常都需要一个close函数来关闭套接口,来中断TCP的连接。

int close(int sockfd);

(7)send()函数

当连接建立了后自然就需要数据的传送和接收,send()函数是用来想连接

的另外一端发送数据。

int send(int sockfd,void *buf,int len,int flags);

第1个参数是已经连接的套接口的描述符,第2个参数是发送的数据的内

存地址,第3个参数是发送数据的大小,第4个参数是选项。

(8)recv()函数

数据发送到接收端了后,就可以用recv()函数来接收由发送端发送过来的

数据了。

int recv(int sockfd,void *buf,int len,int flags)

第1个参数是已经连接的套接口的描述符,第2个参数是发送的数据的内

存地址,第3个参数是发送数据的大小,第4个参数是选项。

5 程序设计和流程图

5.1 设计思路

本课题是采用C/S模式。客户程序功能是界面的编写,并和服务程序通信。

采用GTK编写界面,采用Sock编程实现通信。服务器程序功能是接收客户程序

的数据,并且通过收到的数据来完成系统或应用服务程序文件的配置。在Linux

中服务配置文件主要是以文本文件的形式存在的,所以通过Linux系统调用很

容易修改配置文件,流程如图2。

main()

建立连接(TCP3次握手)

输入服务器IP

连接界面

连接

成功

连接不成功 初始化数据

用户主界面

用户操作

退出

结束

图2 程序总体流程

等待连接

TCP接口

TCP接口

处理

请求

退出

结束

5.2 服务程序

5.2.1 流程设计

服务程序功能有两个:一是监听端口,接收数据和向客户程序发送数据;

二是根据客户程序发送过来的数据对文件修改,其流程图如图3所示。

图3显示了服务程序的流程,accept()是监听端口,等待客户程序的连接,

连接建立好后init_clinet()函数从配置文件读取服务器的当前配置文件数

据,然后再发送到客户程序,让客户程序通过这些数据来初始化界面。然后再

接收客户程序的数据(流程控制字符串),通过判断字符串来控制服务程序的流

程(图3中的虚线部分)。

图3 服务程序的流程图

recv ()

连接建立

TCP3次握

init_clinet ()

close ()

一直阻塞到

客户连接到

listen()

accep()

sock()

bind()

程序入口

字符串

对字符

判断处理

判断

exit

user

group sysconfig

dnsconfig

apachecon

vsftpcon

user_control()

InitAction ()

group_control()

Apache_Config ()

Ftp_Config () Net_DNS_Config ()

5.2.2 功能模块

(1) 系统用户管理操作

和客户程序建立了连接,并且收到了user字符串后,服务程序进入系统用

户管理操作模块,接着接收客户程序发送过来的数据(字符串),通过数据来判

断是对用户的添加、删除、浏览或修改操作。接收到了“adduser”字符串就进

入添加用户流程;接收到“deluser”字符串就进入删除用户流程;接收到

“scanuser”字符串就进入了浏览用户流程;接收到“property”字符串就进

入到了修改用户流程,系统用户管理操作流程如图4所示。

把读取数据存

到2维数组

temp中

fget()

fopen()

recv()

把接受的

数据格式

化存储在

字符串

str中

exit

user_control()

recv()

字符

property

adduser

scauser

recv()

fopen()

fget()

send()

recv()

把接受的

数据格式

化存储在

字符串

把读取数据存

str中

fopen()

fget()

相同

到2维数组

temp中

fopen()

为空

接收的字

符和读取

不同

fclose()

为空

fclose()

fopen()

把temp中的数

据fputs()到文

件中

把temp中的数

据fputs()到文

件中

不同

fopen()

把读取数据

把str存到2维

存到2维数

数组temp中

组temp

相同

接收的字

符和读取

fget()

为空

fclose()

fopen()

fputs(str)

退出用户操作

到图3的recv()

把temp的数据

fputs()到文件

图4 用户操作流程

对用户的操作是添加、删除和修改用户,Linux用户都是记录在

/etc/passwd文件中,对用户添加、删除和修改都是通过修改/etc/passwd文件

来实现。/etc/passwd的用户都是按照统一存格式来存储,格式举例如下:

terrycheops:x:500:500:terrycheop:/home/terrycheops:/bin/bash

存储中每个字段都用“:”隔开的,第一字段:用户名(也被称为登录名),

在上面的例子中,我们看到用户的用户名是terrycheops;第二字段:口令,在

例子中我们看到的是一个x,其实密码已被映射到/etc/shadow 文件中;第三字

段:用户的ID;第四字段:用户组的ID;第五字段:用户名全称,可选项;第六

字段:用户的家目录所在位置,该用户的是/home/terrycheops。第七字段:用

户所用Shell的类型,一般设置为/bin/bash。

程序进入到了添加用户后,接收客户程序传过来要添加的用户信息(用户

名、密码、全名)。把客户程序发送过来的用户密码用MD5算法加密,把加密后

的密码和用户其他数据按照/etc/passwd的格式复制到字符串变量(str)中。用

C语言的流的读操作打开文件/etc/passwd,读取/etc/passwd中的每一行,把

每次读取的数据都复制到二维数组(temp)中,关闭文件。再以写的形式打开文

件,然后把上面二维数组(temp)的内容写到文件中,最后再把变量(str)写到文

件中,这样就实现了用户的添加。

程序进入到了删除用户流程后,接收客户程序要删除用户的用户名。用C

中流的操作打开文件/etc/passwd,判断读取的数据,当要删除的用户名和读取

的用户名一致时就不把这个用户信息复制到二维数组(temp);读取用户名和删

除用户名不一样就把读取数据复制到temp中。然后关闭这个流。重新以写文件

的操作打开文件/etc/passwd,然后把二维数组(temp)中的数据的以流的形式在

写入到文件/etc/passwd中,这样就实现了用户的删除。

用户修改过程,接收客户程序发送过来的数据后,把接收的数据格式化复

制到str中。以C语言中流的操作打开并且读取文件/etc/passwd的数据,判断

读取的数据,当要修改的用户名和读取的用户名一致时把str数据复制到二维

数组(temp);读取用户名和修改的用户名不一致时就把读取数据复制到temp

中。然后关闭这个流。重新以写文件的操作打开文件/etc/passwd,然后把二维

数组(temp)中的数据以流的形式再写入到文件/etc/passwd中,这样就完成了

修改用户的操作

当进入浏览用户的流程后,打开/etc/passwd文件,把文件的数据读取到

buff中,再关闭文件,把buff的数据发送的到客户程序,让客户程序显示当

前的用户信息。

(2) 系统用户组的操作

用户组(Group)配置文件主要有 /etc/group和/etc/gshadow,其中

/etc/gshadow是/etc/group的加密信息文件。etc/group 文件是用户组的配置

文件,内容包括用户和用户组,并且能显示出用户是归属哪个用户组或哪几个

用户组,因为一个用户可以归属一个或多个不同的用户组;同一用户组的用户

之间具有相似的特征。对组的操作都是通过修改/etc/group来实现的,主要是

对组的添加删除和修改。

进入到组添加流程后,接收客户端发送过来要添加的组的信息,然后把接

收的数据格式按照/etc/group存储格式格式化后复制到str中。然后打开文件

/etc/group,读取文件中组的数据复制到二维数组(temp)中,关闭文件。在打开

文件/etc/group把temp的数据写到文件中去,最后把str写入到文件中,关

闭文件,这样就实现了组的添加。

组的删除过程,读取客户程序发送过来的数据,然后打开/etc/group文件,

读取文件的数据,当读取的数据和发送过来的组名一样,就不把读取数据复制

到二维数组(temp)中,其它都把读取的数据复制到temp中,关闭打开的文件。

再次打开文件/etc/group,把temp的数据都写到文件中,关闭文件,这样就完

成组的删除操作。

组的修改过程,接收客户端发送过来要添加组的信息,然后把接收的数据

格式按照/etc/group存储格式格式化后存复制到str变量中。然后打开

/etc/group文件,读取文件的数据,当读取的数据和发送过来的组名一样,就

把str复制到temp中,其它都把读取的数据复制到temp中,关闭打开的文件。

再次打开文件/etc/group,把temp的数据都写到文件中,关闭文件,这样就完

成组的修改操作。

浏览组的过程,当程序到了浏览组的流程后,打开/etc/group文件,把文

件的数据读取到buff中,再关闭文件,把buff的数据发送的到客户程序。让

客户程序显示当前的用户信息。

用户组操作的流程如图5所示。

fopen()

把读取数据存

到2维数组

temp中

为空

fclose()

fget()

把接收的

数据格式

化存储在

字符串

str中

fopen()

recv()

exit

group_control()

recv()

字符

property

groupadd

groupsca

recv()

fopen()

fget()

send()

recv()

把接收的

数据格式

化存储在

字符串

str中

把读取数据存

到2维数组

temp中

fopen()

fget()

相同

接收和读

取字的符

fopen()

为空

不同

fclose()

fopen()

把temp中的数

据fputs()到文

件中

不同

把temp中的数

据fputs()到文

件中

退出组的操作

fputs(str)

到图3的recv

函数

把读取数据

把str存到2维

存到2维数

数组temp中

组temp中

相同

接收和读

取的字符

fget()

为空

fclose()

fopen()

把temp中的数

据fputs()到文

件中

图5 组操作流程

(3) 系统服务启动管理

系统服务启动管理和其他的操作不大一样,其他的操作是通过修改配置文

件来实现的,而系统服务的启动是通过添加和删除链接文件来完成的。其流程

如图6所示。

InitAction ()

退出系统启

动服务管理

到图3的

recv()

1

第5个

字符

0

1

第4个

字符

0

第3个

字符

0

unlink(“/etc/rc.d/rc5.d/

S80sendmail”)

link(“/etc/init.d/dhcp”,

“/etc/rc.d/rc5.d/S65dhcpd”)

1

第2个

字符

0

unlink(“/etc/rc.d/rc5.d/S85htt

pd”)

link(“/etc/init.d/sendmail”,

/etc/rc.d/rc5.d/S80sendmail”)

1

1

第1个

字符

0

recv ()

link(“/etc/init.d/named”,

“/etc/rc.d/rc5.d/S11named”)

unlink(“/etc/rc.d/rc5.d/S11nam

ed”)

link(“/etc/init.d/httpd”,

“/etc/rc.d/rc5.d/S85httpd”)

unlink(“/etc/rc.d/rc5.d/

S65dhcpd”)

link(“/etc/init.d/smb”,

“/etc/rc.d/rc5.d/S91smb”)

unlink(“/etc/rc.d/rc5.d/

S91smb”)

图6 系统启动服务管理流程

服务程序进入到图3的InitAction()函数就进入了系统服务启动管理流

程,接收客户程序发送过来的数据,这里发送过来的是一个有5个字符串的数

组。判断字符串的第1个字符,如果是1的话就调用系统调用link()把

/etc/init.d/named shell脚本链接为/etc/rc.d/rc5.d/S11named文件;如果

字符是0就调用unlink()取消/etc/rc.d/rc5.d/S11named文件的链接。然后再

判断第2个字符,是1就把/etc/init.d/http shell文件链接为

/etc/rc.d/rc5.d/S85httpd文件;如果第2个字符是0,就取消文件

/etc/rc.d/rc5.d/S85httpd的链接。然后判断第3个字符,是1就调用系统

linnk()函数把/etc/init.d/sendmail链接到/etc/rc.d/rc5.d/S80sendmail,

是0就取消对/etc/rc.d/rc5.d/S80sendmail的链接。然后就判断第4个字符

的值,如果是1话就把/etc/init.d/dhcp hell脚本链接为文件

/etc/rc.d/rc5.d/S65dhcpd,是0就取消对/etc/rc.d/rc5.d/S65dhcpd的链接。

最后再判断第5个字符,是1就把文件/etc/init.d/smb为文件

/etc/rc.d/rc5.d/S91smb。否则就取消对/etc/rc.d/rc5.d/S91smb的链接。

(4) DNS管理操作

图3的程序流程到Net_DNS_Config()函数就进入DNS功能模块了。该模块

主要是为在DNS中添加和删除zone;在zone中添加和删除domain。进入该模

块后,服务程序会接收一个客户程序发送的数据,该数据用来控制DNS模块的

流程,其流程如图7所示。

退出系统启

动服务管理

到图3的

recv()

退出系统启

动服务管理

到图3的

recv()

退出系统启

动服务管理

到图3的

recv()

退出系统启

动服务管理

到图3的

recv()

删除

domain

操作

添加

zone

操作

删除

zone

操作

删除

domain

操作

delinzone

addzone

delzonel

字符

addtozone

Net_DNS_Config () recv()

图7 DNS流程图

添加zone操作先接收客户程序发送过来的数据(要添加的zone名字和类

型),通过zone的名字加入点格式后在判断配置文件中有没有zone存在,如果

存在就发送一个“zone name is exist”字符串到客户端,退出DNS配置,不

存在再把zone字和类型格式化为/var/named/chroot/etc/中zone

存储格式,然后把格式化后的数据存储到配置文件中,存储成功后发送“zone

add succseed”到客户程序。

删除zone操作先接收客户程序发送过来的数据(要删除的zone名),判断

配置文件中是否有发送过来zone名存在,如果没有就向客户发送“zone name is

not exist”字符串;如果有就读取配置文件的数据到内存(buff)中,再把buff

内存中的数据删除要删除的部分,然后再把buff中的数据写入到配置文件中。

写入成功后发送“zone delete succsed”字符串到客户程序。

添加domian操作先接收客户程序发送过来的数据(要添加的domain名,IP

和zone名),然后判断/var/named/chroot/etc/中是否有这个zone

存在,没有就发送“zone name is not exist”到客户程序,如果有就得到其

数据文件名字。然后把domian和IP格式化后写入到数据文件中。

删除domain操作先接收客户程序发送的数据(要删除的domain,和zone),

然后判断/var/named/chroot/etc/中是否有这个zone存在,如果

没有就发送“zone name is not exist”到客户程序,如果有就得到其数据文

件名字,然后在数据文件中查看是否有domain存在,如果没有就发送“Domain

name is not exist”到客户程序,如果有就删除domain部分,然后发送“Domain

del succseed”到客户程序。

(5) Apache服务管理操作

Apache模块主要是完成:向客户程序发送当前的一些Apache错误日志;

通过客户发送过来的数据进行一些简单的配置;Apache服务的开启、关闭和重

启功能,其流程如图8所示。

Apache服务停止、启动和重启操作是通过exec调用Apache停止、启动和

重启的shell脚本来完成的。然后再读取环境变量,然后向客户程序发送操作

结果。

发送配置文件内容操作是读取Apache配置文件的内容,然后把读取的内容

发送到客户程序。

修改配置文件操作,先是接收客户程序发送过来的数据(要修改的内容),

然后在配置文件中查找要修改的位置,把客户程序发送过来的数据写到配置文

件中。

查看错误日志操作,读取错误日志中的数据,在把数据发送到客户程序。

(6) FTP服务管理操作

FTP模块主要完成的是对FTP服务的停止、修改和重启,和通过客户程序

发送过来的数据对FTP的配置文件进行简单的修改。其流程如图9所示。

FTP服务停止、启动和重启操作是通过exec调用FTP停止、启动和重启的

shell脚本来完成的。然后在读取环境变量,然后向客户程序发送操作结果。

发送配置文件内容操作是读取FTP配置文件的内容,然后把读取的内容发

送到客户程序。

修改配置文件操作,先是接收客户程序发送过来的数据(要修改的内容),

找到要修改数据的位置,把收到的数据写入到文件中。

退出系统启

动服务管理

到图3的

recv()

服务停服务启服务重

启操作

发送配

置文件

内容

修改配

置文件

的操作

查看错

误日志

的操作

止操作 动操作

字符

stop

viewlog

start

refresh

saveconfig

Net_DNS_Config () recv()

restart

图8 Apache流程图

Net_DNS_Config () recv()

字符

stop

start

refresh

saveconfig

restart

服务停服务启服务重

启操作

发送配

置文件

内容

修改配

置文件

的操作

止操作 动操作

退出系统启

动服务管理

到图3的

recv()

图9 FTP流程图

5.3 客户程序

5.3.1 设计思路

客户端的作用有两个:一是为用户提供操作界面;二是和服务器端进行数

据通信。

在用户界面方面,采用GTK编程来建立用户界面,把实现的功能接口通过

界面的方式提供给用户,让用户来进行相关的操作。在和服务器通信方面是通

过SOCK编程来实现的。把用户操作后的结果通过SOCK来传达给服务器程序。

让服务器程序通过SOCK传递的数据来对服务器的配置。

在模块划分方面。主要是通过功能来划分为:用户和组的操作、DNS配置、

Apache的配置、FTP的配置、启动服务管理。

5.3.2 程序设计

客户程序一共有两个窗体,连接窗体和主窗体。

 连接界面的编写

首先是连接界面的编写,主要是用于和服务器端的连接。除了用GTK编写

界面以外还要用到SOCK编程来进行和服务器端的TCP连接的建立。连接界面是

这个程序的第1个界面,其流程图如图10所示。

main()

gtk_init()

CForm()

按下连接按钮

sock()

连接建立

connect()

TCP3次握手

连接成功

图10 连接界面的流程图

主界面

程序从main()进入以后就调用gtk_init()函数。gtk_init()函数功能初始化

GTK,并且分析在命令行中传递进来的参数。命令行中传递过来的任何参数,只

要是它能识别的,都会从列表中删除,并且修改argc和argv的值,就像这些参数

从不存在一样,然后应用程序分析剩余的参数。

然后进入CForm()函数。这个函数主要功能是创建连接界面,并且当用户

在文本框中输入了服务器IP地址后,把文本框中的IP传递给后面的函数,实

现与服务器网络连接。其函数代码如下:

GtkWidget *textbox;

void CForm(int *sock)

{

GtkWidget *exitButt,*clloButt,*clloLabl;

GtkWidget *table;

int level;

char *text;

mainWin = gtk_window_new(GTK_WINDOW_TOPLEVEL);

gtk_window_set_title((GtkWindow*)mainWin,"connet");

gtk_window_set_default_size((GtkWindow*)mainWin,80,90);

exitButt = gtk_button_new_with_label("exit");

clloButt = gtk_button_new_with_label("connect");

clloLabl = gtk_label_new("Servers IP");

textbox = gtk_entry_new();

table = gtk_table_new (2, 3, TRUE);

gtk_table_set_row_spacing(GTK_TABLE(table),1,10);

gtk_table_set_row_spacing(GTK_TABLE(table),0,10);

gtk_table_set_col_spacing(GTK_TABLE(table),1,35);

gtk_entry_set_text((GtkEntry *)textbox,"input severs IP here!");

text = gtk_entry_get_text((GtkEntry *)textbox);

gtk_table_attach_defaults((GtkTable*)table,clloLabl,0,1,0,1);

gtk_table_attach_defaults((GtkTable*)table,textbox,1,2,0,1);

gtk_table_attach_defaults((GtkTable*)table,clloButt,0,2,1,2);

gtk_table_attach_defaults((GtkTable*)table,exitButt,0,2,2,3);

gtk_container_set_border_width (GTK_CONTAINER (mainWin), 0);

gtk_container_add (GTK_CONTAINER (mainWin), table);

gtk_signal_connect(GTK_OBJECT(exitButt),

"clicked",

GTK_SIGNAL_FUNC(Destroy),

NULL);

gtk_signal_connect(GTK_OBJECT(mainWin),

"destroy",

NULL,

NULL);

gtk_signal_connect(GTK_OBJECT(clloButt),

"clicked",GTK_SIGNAL_FUNC(CollFunc),

sock);

gtk_signal_connect_object(GTK_OBJECT(exitButt),

"clicked",GTK_SI GNAL_FUNC(Destroy),

GTK_OBJECT(mainWin));

gtk_widget_show(mainWin);

gtk_widget_show(exitButt);

gtk_widget_show(clloButt);

gtk_widget_show(clloLabl);

gtk_widget_show(textbox);

gtk_widget_show(table);

gtk_main();

}

上面函数大概反映了GTK变成中常用的构件和函数。前面对里面大部分代

码介绍过了。这里就不详细介绍了。但是需要指出的是

gtk_signal_connect(GTK_OBJECT(clloButt),

"clicked",

GTK_SIGNAL_FUNC(CollFunc),

sock);

这个函数主要是用来绑定X事件,也就是当用户按下了连接按钮后调用

CollFunc()这个函数。CollFunc()主要作用是读取文本框中的字符,并且用这

个来作为连接服务器的IP,向服务器提出连接请求,连接成功就进入主界面,

并且销毁连接界面的构件。不成功就返回到连接界面。CollFunc()函数如下:

void CollFunc( GtkWidget *widget,gpointer data )

{

int *sock,result;

char *text = NULL;

sock = data;

text = gtk_entry_get_text((GtkEntry *)textbox);

*sock = make_clinet_sock(text,13000);

if(*sock < 0){return ;}

init_clinet(sock);

mainform(sock);

gtk_widget_destroy(mainWin);

}

 主界面

当用户端和服务器端连接成功后,就进入主窗体流程了,在主窗体建立前

要接收一些从服务程序发送过来的数据,然后把这些数据存放到一些临时文件

里面,等待具体创建窗体的时候调用这些数据来初始化界面。其流程如图11

所示。

gtk_widow_new UserControl

Apache DNS InitServer GroupContro

ftp gtk_main()

把控制权战时交给了X系统等待用户操作

图11 主界面的大概流程图

主窗体有各个功能模块的操作页面,程序主界面如图12所示。

图12 程序主界面

(1)用户操作

Linux 是一个多用户、多任务的操作系统。在用户操作方面我们主要实现

的是对用户的添加,删除和修改。当主界面创建好了后就等待用户的操作了,

用户的操作界面如图13所示。

图13 用户操作界面

添加用户:当用户按了添加用户按钮后,就调用了User_Add()函数对这个

事件来响应。其功能是创建一个临时界面,让用户输入要添加的用户的用户名

和密码,在判断了输入文本框都不为空的时候,先传递给服务器一个“User”

字符串,再传递一个一个“adduser”字符串,这些的传递是为了让服务器能够

首先通过判断这些字符串来到添加用户流程里面。其界面如图14所示。

图14 添加用户界面

当图14的Entry按键被按下了后,就从上图中的文本框中读取字符串,再

判断字符串是否为空,不为空就把UserNane,FullName,Password所对应的字符

串分别传递服务器端。让服务器端通过传递过来的数据实现添加用户。然后再

从服务器端读取操作的结果。在把结果显示给用户。如图15所示。

图15 添加用户返回

删除用户:选种了列表中的要删除的用户,这个时候程序会调用

selection_call_back()函数。把用户所选种的列表框的用户的信息保存在全句

变量中。删除按钮后被按下了后,就调用User_Del()函数。User_Del()函数先

向服务器发送一个“User”字符串,和传递一个“deluser”字符串,然后就把

要删除的用户名发送给服务程序。再接收服务程序发送过来的操作结果,显示

给用户。

修改用户:当用户从列表框里面选中了要修改的用户后,和删除用户操作

一样的会调用selection_call_back()函数,把操作用户所选中的用户保存在

一个全局变量中。图14中的Porperty被点击了后,创建一个临时的窗体,用

来显示当前所选中的用户属性。并且向服务程序发送一个“User”字符串,其

界面图如16所示。

图16 用户属性界面

OK按钮所触发的事件是先向服务器发送一个“property”字符串,然后读

取文本框中的数据,把这些数据一起发送给服务程序。

cancel按钮所触发的事件是向服务器发送一个“exit”字符串。

刷新按钮所触发的事件是:调用UserScan()函数。这个函数主要作用是向

服务器端发送一个“userscan”字符串,然后服务程序会读取这个时候的

/etc/passwd的内容,并且传递给发送到客户程序,客户程序把服务程序传过

来的数据存储在临时的文件里面,然后把列表框中的数据清空,在从临时文件

中读取当前的用户信息,重新显示在列表框中来。

(2) 用户组的操作:具有某种共同特征的用户集合起来就是用户组

(Group)。在Linux系统中文件的访问权限有这严格的规定,组在Linux系统

中有很重要的作用。和上面用户的操作过程大概相同,当组页面建立好了后,

马上就从客户端创建的临时文件中读取服务器当前的组状态。用来初始化列表。

组的操作的界面如图17所示。

添加组:添加组的事件是在GroupAdd按钮按下了后,先是向服务程序发送

一个“group”字符串和“addgroup”字符串。然后再把从组添加组界面得到的

数据发送到服务程序。等服务程序返回结果了后,再把服务程序返回的结果显

示给用户。

删除组:删除组的操作大概过程和删除用户相似,也是在选中了要删除的

组后,调用group_selection_call_back()函数,来把组的组名等信息存储在

一个全局变量中。当用户按下了GroupDel按钮后,向服务器端发送一个“group”

字符串和一个“delgroup”字符串,然后发送要删除的组名到服务器程序。通

过服务器程序来删除服务器端的组。接收服务程序发送过来的操作结果,把结

果显示给用户。

刷新组:当刷新按钮被按下了后就调用group_fresh_button_click ()函

数。这个函数主要作用是向服务器端发送“group”字符串和“refresh_group”

字符串,然后服务程序会读取这个时候的组配置文件的内容,传递给客户程序,

客户程序把服务器传过来的数据存储在临时的文件里面,然后把列表框中的数

据清空,再从临时文件中读取当前的用户信息,重新显示在列表框中来。

图17 用户组的操作界面图

(3) 系统服务初始化

系统服务初始化,主要是对系统要启动的服务管理,是否要在系统启动的

时候启动这些服务。在Linux系统中有60多个启动服务,但是这里我们就选了

五个常用的服务来配置。操作界面如图18所示。

图18 系统启动服务管理

当这个界面创建好了后,就要从服务器端接收一个字符串数组,这个字符

串数组只有0或者1。客户端接收了数组后,通过这些字符来判断当前服务器

的启动项目中有没有这些服务的启动,有就在相应的服务上面打勾,没有就不

打。用于显示服务名的构件是check按钮构件,这个构件是特殊的按钮。这些

按钮所对应的事件是设置其Active属性。

Save按钮所对应的回调函数是main_init_save_click(),该函数先向服务

程序发送“sysconfig”和“save”字符串。然后分别读取5个check按钮的

Active属性,再根据其Active属性来设置要发送的数据,然后就是发送数据

到服务程序。

Freash按钮对应的回调函数作用,是先发送一个“sysconfig”和“freash”

字符串,然后就接收服务器端的数据,通过传过来的数据来设置每个开关按钮

的Active属性。

(4) DNS服务管理操作

DNS服务是一个IP到域名的转换服务,其配置界面如图19所示。

图19 DNS的配置界面

DNS中所显示服务器的zone是采用树构件,这个构件在创建的时候就要对

其初始化。也就是把接收到的服务器的信息建立在树构件里面,树的构件过程

相对列表要复杂点。先是从临时的DNS配置文件中读取zone的名字,显示在树

的根部,然后再向服务程序发送zone的名字,服务器端再通过zone的名字,

将从其对应的数据文件中读取Domain的信息,再返回给客户端,客户端接收了

这个返回信息后,通过信息来建立子树。

添加zone:添加zone按钮所对应的事件,调用main_dns_addzone_click()

函数,然后建立一个临时的窗体,用来记录要创建的zone名字和类型。然后再

读取这些信息后,向服务器端发送一个“dnsconfig”字符串和一个“addtozone”

字符串和记录的zone名字和类型。让服务器通过发送的字符来添加zone。最

后接收一个由服务程序发回来的返回值,并显示添加的操作是否成功。

删除zone:当用户选用了一个顶树,把树的名字传递给一个全局变量中,

然后向服务器发送一个“dnsconfig”字符串和一个“delzone”字符串,后就

向服务程序传送要删除的zone的名。然后接收一个由服务器返回来的值,并显

示删除操作是否成功。

在zone添加成功后,有时候我们要向zone里面添加和删除一些Domain

的信息。下面就是这些操作的过程。

添加Domain:addDomain按钮的回调函数作用是:显示一个窗题,并且在

窗体中输入了要添加到zone的domain后,并且按下了确定按钮后,先向服务

端发送一个“netdnsconfig”和一个“addtozone”字符串,让服务程序进入添

加的domian 流程,然后把窗体文本框的数据读取后发送到服务程序。

(5) Apache服务

Apache服务是一个WEB服务,其配置界面如图20所示。

图20 Apache配置界面

在它的界面建立的同时,也要从一个临时文件中读取从服务程序传送过来

的原配置文件的信息,示给用户,用户可以通过文本框和Label看到现在Apache

配置文件的一部分信息。

VieErroLog按钮的回调函数作用:先向服务器端发送“Apachecon”和

“viewlog”字符串,等服务器端从错误日志文件中读取数据,然后把数据发送

到客户端,客户端在读取这些数据,然后再创建一个临时窗体来显示这些数据,

临时窗体如图21。

图21 错误日志查看界面

save按钮回调函数作用:先向服务程序发送“Apachecon”和“saveconfig”

字符串,然后再把从文本框中读取的数据组合后发送到服务程序。

restart按钮回调函数作用:先向服务程序发送“Apachecon”和“restart”

字符串,然后等待服务程序把Apache服务重启后,返回操作结果,把操作结果

显示给用户。

stop按钮回调函数作用:先向服务程序发送“Apachecon”和“stop”字

符串,然后等待服务程序把Apache服务重启后,返回操作结果,把操作结果显

示给用户。

start按钮回调函数作用:先向服务程序发送“Apachecon”和“start”

字符串,然后等待服务程序把Apache服务重启后,返回操作结果,把操作结果

显示给用户。

(6) FTP服务管理操作

FTP界面建立的同时要从临时文件夹中读取数据来初始化一些界面。其界

面如图22所示。

图22 FTP界面

save按钮回调函数作用:向服务程序传送“ftpconf”和“save”字符串,

让其流程到保存配置文件中去,然后在读取文本框中的数据格式化后发送到服

务程序去,让服务程序按照发送的数据去修改FTP的配置文件。

refresh按钮回调函数作用:先向服务程序发送“ftpconf”和“refresh”

字符串,然后接收服务程序发送过来的数据,把数据保存到临时文件里面,在

按照初始化界面的流程来把文本框中数据更新。

类似的resart按钮回调函数作用是先向服务程序发送“ftpcong”和

“restart”字符串;stop按钮回调函数作用也是先向服务程序发送“ftpcong”

和“stop”字符串;start按钮回调函数作用也是先向服务程序发送“ftpcong”

和“start”字符串。

6 系统测试

测试总体结果,基本上完成了预期的功能,能够实现用户管理操作和系统

应用服务的配置管理。但是,在测试的时候发现如果用户操作过快可能导致服

务器死机。这是因为服务器端流程是通过客户端发送的字符串来引导的,如果

操作过快发送的字符串就有可能错乱,从而没有达到想要的流程。

本系统安全性也不是太好,在服务程序打开的时候,另外的程序可以通过

发送和客户端相同的字符串来完成非法的添加用户,修改配置文件等。

权限问题也是本系统不完善的地方,在Linux中用户的权限是很重要的,

本程序只能以root连接才能完全的运行,如果不是root,里面很多的文件就

不能查看和配置。

结 论

通过本次课题的研究,本程序基本实现了对用户和组的添加、修改和删除;

对DNS、Apache、FTP和系统初始启动服务的修改。但是这个系统还不够健壮,

从测试可以看到当用户操作过快的时候容易导致服务端流程混乱,解决这个问

题,可以对服务器端加上多线程的操作。在安全性方面,可以加入一些加解密

的算法来避免一些非法的修改,由于毕业设计时间短暂,很多需要的改进的地

方还来不及,所以在今后的工作中继续进一步完善该软件系统。

当然,本软件系统仅仅实现了常见的系统服务管理,还有更多的服务需要

增加。比如邮件功能,在Linux中应用也是很广泛的,可以加入邮件的收发功

能,也可以加入系统进程查看和终止系统功能等等,需要增加的功能和现在已

实现的方法一样,只是需要搞清楚各种服务的配置文件格式和内容,以及启动

服务的程序就可以完成功能的增加。最终通过程序的设计和实现,使我对网络

编程和软件开发的各项流程有了更进一步的认识,并巩固了所学的知识。

参考文献

[1] Bruce Molay(美)著 .Unix/Linux编程实践教程[M].北京:清华大学出版社.2004。

[2] Richard Stenvens,Bill Fenner(美). Unix网络编程[M].北京:清华大学出版.2001。

[3] RobertLove(美)著.Linux内核设计与实现[M].北京:机械工业出版社.2004。

[4] Brian han Dennis e(美).C程序设计语言[M].北京:机械工业出版

社1999。

[5] 许宏松. Linux应用程序开发指南:使用Gtk+/Gnome库[M].北京:机械工业出版社

2000。

[6] Matt Welsh,Matthias Kalle Dalheimer,Lar Kaufman著.LINUX权威指南(第三版)[M].

北京: 中国电力出版社.1999。

[7] Olof er Karin Kylander著.GIMP权威指南[M].北京: 机械工业出版社.2001。

致 谢

本文是在刘嘉勇老师的热情关心和指导下完成的,他们丰富的知识和严谨

的治学作风使我受益匪浅,在Linux系统管理操作、Linux远程管理技术分析、

系统管理规划和设计方面得到了极大的帮助,对顺利完成本课题起到了极大的

作用。在此向他表示我最衷心的感谢!

在论文完成过程中,在程序调试和Linux系统的具体管理和操作技术方面,

本人还得到了秦智老师和徐斌同学的热心帮助,本人向他们表示深深的谢意!

最后向在百忙之中评审本文的各位专家、老师表示衷心的感谢!


本文标签: 用户 函数 构件