Linux下基于文本文件的员工管理系统,本地和基于socket的Server端和Client端
一、基本要求
1、Linux环境实现简单的员工管理系统
1) *在Linux系统运行,使用Makefile, *.C源文件分布在两个目录中。
2) *创建基于文本文件的本地员工信息管理系统。
3) *可以增,删,改员工信息。
4) *员工信息包含至少3个数据段,比如工号,英文姓名,年龄,工龄等等。
5) *可以显示所有员工信息。
6) *可以按照关键字检索显示匹配的员工信息。比如:
• 查找某工号的员工
• 查找年龄大于或者小于多少的员工
7) 本地保存的信息按照某个字段排序。
8) *应用程序需要有指令帮助信息,自行设计指令菜单,需要有二级菜单,比如:
※如下只是举例,不用完全按照这个做,但是必须要有二级菜单
********** 菜单 **********
1 - 员工信息查询
- 姓名查找
- 年龄查找
- 工号查找
- 返回
2 - 员工信息更新 - 新增员工资料
- 删除员工资料
- 修改员工资料
- 返回
3 -员工信息排序 - 按照年龄排序
- 按照工号排序
- 返回
0 – 退出
2、Linux环境实现远程访问员工管理系统
1) *前题目改造成客户端和服务器端的形式。
2) *客户端负责信息输入和输出显示。
3) *服务器端负责数据保存和整理。
4) *客户端和服务器端使用TCP进行沟通。
5) *实现多客户端同时访问服务器功能(增,删,改),包括本地和远程
6) *应用程序需要有命令使用帮助信息
使用双向链表对员工信息进行增删查改和排序,使用文本文件进行员工信息的存储,使用Socket进行Client端和Server端的通信,对于服务器同时响应多个客户端的连接请求,我使用的是多线程。
以下是代码:
二、本地版本
1、List.h
这是双向链表的头文件,包括一些宏。
#ifndef LIST_H
#define LIST_H
#define TO_FILE "/home/liuyin/test/project/test/server/list.data"
typedef struct Node* PNode;
typedef PNode Position;
/*节点结构*/
typedef struct Node
{
//int data; //数据域
char num[20]; //work number
char name[20]; //name
char sex[20]; //sex
char age[20]; //age
char tel[20]; //phone
PNode pre; //前驱指针
PNode next; //后继指针
}Node;
typedef struct
{
int size;
PNode head;
PNode tail;
}List;
//PNode InitList(List *plist);
//分配节点,并返回节点地址
Position MakeNode();
struct List *Create();
//构造一个空的双向链表
List *InitList();
void clearlist(List *plist);
void clearlist1(List *plist);
//清空链表
void destroylist(List *plist);
//返回头节点地址
Position GetHead(List *plist);
//返回尾节点地址
Position GetTail(List *plist);
//返回链表大小
int GetSize(List *plist);
//判断链表是否为空
int IsEmpty(List *plist);
//删除头节点
void DelFirst(List *plist);
//删除尾节点
void DelEnd(List *plist);
//删除中间节点
void DelMind(List *plist);
#endif
2、FileManagement.h
这是对文件操作的头文件,因为有用到链表,所以包含了List.h。
#ifndef FILEMANAGEMENT_H
#define FILEMANAGEMENT_H
#include "List.h"
//写入info文件
void WriteFile(List *plist);
//读取info文件
void ReadFile(List *plist);
#endif
3、localhandle.h
这是本地员工管理系统定义的一些操作函数。
#ifndef LOCALHANDLE_H
#define LOCALHANDLE_H
#include "List.h"
//一、员工信息更新,按0返回
//1.新增员工资料
void Add(List *plist);
//2.删除员工资料,按工号删除
void DelNum(List *plist);
//3.修改员工资料
void ChangeNum(List *plist);
//二、员工信息查询
//按工号删除和修改用的查找
PNode FindNum1(List *plist,char *num);
//1.姓名查找
PNode FindName(List *plist);
//2.工号查找
PNode FindNum(List *plist);
//3.年龄查找(大于多少,小于多少)
PNode FindAge(List *plist);
//三、员工信息排序
//1.按年龄排序
void SortAge(List *plist);
//2.按工号排序
void SortNum(List *plist);
//遍历员工信息
void travel(List *plist);
//清空员工信息
void destroy(List *plist);
#endif
4、List.c
对List.h种定义的一些函数进行实现。
#include "List.h"
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
//分配节点,并返回节点地址
Position MakeNode()
{
PNode p = NULL;
p = (PNode)malloc(sizeof(Node));
if (NULL != p)
{
p->pre = NULL;
p->next = NULL;
}
return p;
}
//构造一个空的双向链表
List *InitList()
{
List *plist = (List *)malloc(sizeof(List));
PNode head = MakeNode();
if (NULL != plist)
{
if (NULL != head)
{
plist->head = head;
plist->tail = head;
plist->size = 0;
}
else
{
return NULL;
}
}
return plist;
}
void clearlist(List *plist)
{
if (NULL == plist->head)
{
return;
}
PNode p = plist->head->next;
while (NULL != p)
{
PNode temp = p->next;
free(p);
p = temp;
}
plist->head = NULL;
}
void clearlist1(List *plist)
{
PNode p = plist->head->next;
int size = plist->size-1;
PNode temp = NULL;
while (size--)
{
temp = p;
p = p->next;
free(temp);
}
plist->size = 1;
}
//清空链表
void destroylist(List *plist)
{
PNode p = plist->head->next;
int size = plist->size;
PNode temp = NULL;
while (size--)
{
//PNode temp = p;
temp = p;
p = p->next;
free(temp);
}
plist->size = 0;
}
//返回头节点地址
Position GetHead(List *plist)
{
return plist->head;
}
//返回尾节点地址
Position GetTail(List *plist)
{
return plist->tail;
}
//返回链表大小
int GetSize(List *plist)
{
return plist->size;
}
//判断链表是否为空
int IsEmpty(List *plist)
{
if(GetSize(plist) == 0 && GetTail(plist) == GetHead(plist))
{
return 1;
}
else
{
return 0;
}
}
5、FileManagement.c
对文件进行读写操作。
#include "FileManagement.h"
#include "Management.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//写入info文件
void WriteFile(List *plist)
{
FILE * fp = fopen(TO_FILE,"w");
if (NULL == fp)
{
printf("File Not Found!\n");
exit(1);
}
int size = plist->size;
PNode q = plist->head->next;
while (size--)
{
fprintf(fp," %s\t %s\t %s\t %s\t %s\t\n",q->num,q->name,q->sex,q->age,q->tel);
q = q->next;
}
fclose(fp);
}
//读取info文件
void ReadFile(List *plist)
{
destroylist(plist);
FILE *fp = fopen(TO_FILE,"r");
if (NULL == fp)
{
printf("FILE NOT FOUND!");
exit(1);
}
while (0 == feof(fp))
{
PNode q = MakeNode();
fscanf(fp," %s\t %s\t %s\t %s\t %s\t ",q->num,q->name,q->sex,q->age,q->tel);
if (0 == strcmp(q->num," "))
{
break;
}
if (0 == plist->size)
{
plist->head->next = q;
}
else
{
plist->tail->next = q;
q->pre = plist->tail;
}
plist->tail = q;
plist->size++;
}
fclose(fp);
}
6、localhandle.c
对员工管理系统的操作函数的实现,有一些写的不是很好,特别是排序的实现,没有体现双向链表的特点。
#include "localhandle.h"
#include "FileManagement.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static int inputmsg(char *t)
{
int n = strcmp(t,"0");
return n;
}
//一、员工信息更新,按0返回
//1.新增员工资料
void Add(List *plist)
{
while (1)
{
PNode p = MakeNode();
printf("提示:输入0返回更新员工信息菜单!\n");
printf("请输入员工工号:\n");
scanf("%s",p->num);
if (0 == inputmsg(p->num))
{
break;
}
printf("请输入员工姓名:\n");
scanf("%s",p->name);
if ( 0 == inputmsg(p->name))
{
break;
}
printf("请输入员工性别:\n");
scanf("%s",p->sex);
if ( 0 == inputmsg(p->sex))
{
break;
}
printf("请输入员工年龄:\n");
scanf("%s",p->age);
if ( 0 == inputmsg(p->age))
{
break;
}
printf("请输入员工电话:\n");
scanf("%s",p->tel);
if ( 0 == inputmsg(p->tel))
{
break;
}
PNode q = FindNum1(plist,p->num);
if (NULL != q)
{
printf("该工号已存在!\n");
return;
}
if (0 == plist->size)//空链表
{
plist->head = p;
}
else
{
plist->tail->next = p;
p->pre = plist->tail;
}
plist->tail = p;
plist->size++;
printf("一条员工信息已添加!\n");
WriteFile(plist);
}
}
//2.删除员工资料,按工号删除
void DelNum(List *plist)
{
printf("提示:输入0返回更新员工信息菜单!\n");
printf("请输入你要删除的员工工号:");
char num[20];
scanf("%s",num);
if (0 == inputmsg(num))
{
return;
}
PNode p = FindNum1(plist,num);
if (NULL == p)
{
printf("无此员工信息!\n");
return;
}
printf("该员工信息如下:\n");
printf("\n工号 姓名 性别 年龄 电话\n");
printf("\n %s\t %s\t %s\t %s\t %s\t\n",p->num,p->name,p->sex,p->age,p->tel);
//删除头节点
if (p == plist->head->next)
{
plist->head->next = p->next;
}
//删除尾节点
else if (p == plist->tail)
{
plist->tail = plist->tail->pre;
}
//删除中间节点
else
{
p->pre->next = p->next;
p->next->pre = p->pre;
//p->pre->next = p->next;
}
plist->size--;
free(p);
WriteFile(plist);
printf("该员工信息已删除!\n");
}
//3.修改员工资料
void ChangeNum(List *plist)
{
char num[20];
printf("提示:输入0返回更新员工信息菜单!\n");
printf("请输入你要修改的员工工号:");
scanf("%s",num);
if (0 == inputmsg(num))
{
return;
}
PNode p = FindNum1(plist,num);
if (NULL == p)
{
printf("无此员工信息!\n");
return;
}
printf("该员工信息如下:\n");
printf("\n工号 姓名 性别 年龄 电话\n");
printf("\n %s\t %s\t %s\t %s\t %s\t\n",p->num,p->name,p->sex,p->age,p->tel);
printf("请输入新工号:");
scanf("%s",p->num);
printf("请输入新姓名:");
scanf("%s",p->name);
printf("请输入新性别:");
scanf("%s",p->sex);
printf("请输入新年龄:");
scanf("%s",p->age);
printf("请输入新电话:");
scanf("%s",p->tel);
WriteFile(plist);
printf("员工信息修改成功!\n");
}
//二、员工信息查询
//按工号删除和修改用的查找
PNode FindNum1(List *plist,char *num)
{
ReadFile(plist);
PNode p = plist->head->next;
int size = plist->size;
while (size--)
{
if(0 == strcmp(num,p->num))
{
return p;
break;
}
if (NULL != p->next)
{
p = p->next;
}
}
if (p == plist->tail && strcmp(num,p->num) != 0)
{
return NULL;
}
}
//1.姓名查找
PNode FindName(List *plist)
{
char name[20];
int i = 0;
printf("提示:输入0返回更新员工信息菜单!\n");
printf("请输入你要查找的员工姓名:");
scanf("%s",name);
if (0 == inputmsg(name))
{
return;
}
ReadFile(plist);
PNode p = plist->head->next;
int size = plist->size;
while (size--)
{
if(0 == strcmp(p->name,name))
{
printf("\n %s\t %s\t %s\t %s\t %s\t\n",p->num,p->name,p->sex,p->age,p->tel);
i++;
}
p = p->next;
}
if (0 == i)
{
printf("无此员工信息!\n");
}
}
//2.工号查找
PNode FindNum(List *plist)
{
char num[20];
int i = 0;
printf("提示:输入0返回更新员工信息菜单!\n");
printf("请输入你要查找的员工工号:");
scanf("%s",num);
if (0 == inputmsg(num))
{
return;
}
ReadFile(plist);
PNode p = plist->head->next;
int size = plist->size;
while (size--)
{
if(0 == strcmp(p->num,num))
{
printf("\n %s\t %s\t %s\t %s\t %s\t\n",p->num,p->name,p->sex,p->age,p->tel);
i++;
}
p = p->next;
}
if (0 == i)
{
printf("无此员工信息!\n");
}
}
//3.年龄查找(大于多少,小于多少)
PNode FindAge(List *plist)
{
ReadFile(plist);
PNode p = plist->head->next;
int size = plist->size;
char age[20];
int choice = 0;
int i = 0;
printf("提示:输入0返回更新员工信息菜单!\n");
printf("请输入你要查找的年龄界限:");
scanf("%s",age);
if (0 == inputmsg(age))
{
return;
}
printf("请选择大于或小于此界限:1-小于 2-大于 0-返回 :");
scanf("%d",&choice);
if (0 == choice)
{
return;
}
switch (choice)
{
case 1:
while (size--)
{
if(strcmp(age,p->age) >= 0)
{
printf("\n %s\t %s\t %s\t %s\t %s\t\n",p->num,p->name,p->sex,p->age,p->tel);
i++;
}
p = p->next;
}
if (0 == i)
{
printf("无此类员工信息!\n");
}
break;
case 2:
while (size--)
{
if(strcmp(age,p->age) <= 0)
{
printf("\n %s\t %s\t %s\t %s\t %s\t\n",p->num,p->name,p->sex,p->age,p->tel);
i++;
}
p = p->next;
}
if (0 == i)
{
printf("无此类员工信息!\n");
}
break;
default:
printf("输入错误!\n");
}
}
//三、员工信息排序
//1.按年龄排序
void SortAge(List *plist)
{
loop1:
ReadFile(plist);
int size = plist->size;
if (0 == size)
{
printf("员工列表为空!\n");
return;
}
PNode p = plist->head->next;
PNode q = NULL,temp = NULL;
PNode tp = plist->head->next;
PNode mov = tp->next;
PNode phead = plist->head;
if (p && size >= 2)
{
if ((size >= 2) && strcmp(tp->age,mov->age) > 0)
{
if (mov->next)
{
mov->pre->next = mov->next;
mov->next->pre = mov->pre;
mov->next = phead->next;
phead->next->pre = mov;
mov->pre = phead;
phead->next = mov;
}
else
{
mov->pre->next = NULL;
mov->next = phead->next;
phead->next->pre = mov;
mov->pre = phead;
phead->next = mov;
}
}
for (p = p->next;p;p = p->next)//从第二个开始,第一个默认有序
{
temp = p;
for (q = p->pre;q != plist->head->next;q = q->pre)//q从p的前一节点开始往前
{
if (strcmp(q->age,temp->age) <= 0)//升序
{
break;
}
}
if (q->next != p)//如果q有前移,插入temp
{
if (temp->next)//temp不为最后一个节点
{
//temp前后互指,分离temp
temp->pre->next = temp->next;
temp->next->pre = temp->pre;
//插入temp
temp->next = q->next;
q->next->pre = temp;
temp->pre = q;
q->next = temp;
}
else//temp是最后一个节点
{
temp->pre->next = NULL;//temp前一节点的next指为NULL
//插入temp
temp->next = q->next;
q->next->pre = temp;
temp->pre = q;
q->next = temp;
}
}
}
}
WriteFile(plist);
PNode cp = plist->head->next;
PNode cp1 = cp ->next;
if ((size >= 2) && strcmp(cp->age,cp1->age) > 0)
{
goto loop1;
}
}
//2.按工号排序
void SortNum(List *plist)
{
loop2:
ReadFile(plist);
int size = plist->size;
if (0 == size)
{
printf("员工列表为空!\n");
return;
}
PNode p = plist->head->next;
PNode q = NULL,temp = NULL;
PNode tp = plist->head->next;
PNode mov = tp->next;
PNode phead = plist->head;
if (p && size >= 2)
{
if ((size >= 2) && strcmp(tp->num,mov->num) > 0)
{
if (mov->next)
{
mov->pre->next = mov->next;
mov->next->pre = mov->pre;
mov->next = phead->next;
phead->next->pre = mov;
mov->pre = phead;
phead->next = mov;
}
else
{
mov->pre->next = NULL;
mov->next = phead->next;
phead->next->pre = mov;
mov->pre = phead;
phead->next = mov;
}
}
for (p = p->next;p;p = p->next)//从第二个开始,第一个默认有序
{
temp = p;
for (q = p->pre;q != plist->head->next;q = q->pre)//q从p的前一节点开始往前
{
if (strcmp(q->num,temp->num) <= 0)//升序
{
break;
}
}
if (q->next != p)//如果q有前移,插入temp
{
if (temp->next)//temp不为最后一个节点
{
//temp前后互指,分离temp
temp->pre->next = temp->next;
temp->next->pre = temp->pre;
//插入temp
temp->next = q->next;
q->next->pre = temp;
temp->pre = q;
q->next = temp;
}
else//temp是最后一个节点
{
temp->pre->next = NULL;//temp前一节点的next指为NULL
//插入temp
temp->next = q->next;
q->next->pre = temp;
temp->pre = q;
q->next = temp;
}
}
}
}
WriteFile(plist);
PNode cp = plist->head->next;
PNode cp1 = cp ->next;
if ((size >= 2) && strcmp(cp->num,cp1->num) > 0)
{
goto loop2;
}
}
//遍历员工信息
void travel(List *plist)
{
ReadFile(plist);
int size = plist->size;
PNode p = plist->head->next;
printf("员工信息显示如下:\n");
printf("\n工号 姓名 性别 年龄 电话\n");
while (size--)
{
printf("\n %s\t %s\t %s\t %s\t %s\t\n",p->num,p->name,p->sex,p->age,p->tel);
p = p->next;
}
}
//清空员工信息
void destroy(List *plist)
{
destroylist(plist);
WriteFile(plist);
printf("员工信息已全部清空!\n");
}
7、main函数
#include "localhandle.h"
#include <stdio.h>
//更新员工信息
static void UpdateInfo(List *plist)
{
int choice = 0;
while (1)
{
printf("=============更新员工信息============\n");
printf("= 1.新增员工信息 =\n");
printf("= 2.修改员工信息 =\n");
printf("= 3.删除员工信息 =\n");
printf("= 0.返回主菜单 =\n");
printf("=============更新员工信息============\n");
printf("请选择:");
scanf("%d",&choice);
if (0 == choice)
{
break;
}
switch (choice)
{
case 1:
Add(plist);
break;
case 2:
ChangeNum(plist);
break;
case 3:
DelNum(plist);
break;
default:
printf("输入错误!\n");
}
}
}
//查询员工信息
static void FindInfo(List *plist)
{
int choice = 0;
while (1)
{
printf("==============查询员工信息==========\n");
printf("= 1.按姓名查找 =\n");
printf("= 2.按工号查找 =\n");
printf("= 3.按年龄查找 =\n");
printf("= 0.返回主菜单 =\n");
printf("==============查询员工信息==========\n");
printf("请选择:");
scanf("%d",&choice);
if (0 == choice)
{
break;
}
switch (choice)
{
case 1:
FindName(plist);
break;
case 2:
FindNum(plist);
break;
case 3:
FindAge(plist);
break;
default:
printf("输入错误!\n");
}
}
}
//员工信息排序
static void SortInfo(List *plist)
{
int choice = 0;
while (1)
{
printf("===============员工信息排序==========\n");
printf("= 1.按工号排序 =\n");
printf("= 2.按年龄排序 =\n");
printf("= 0. 返回主菜单 =\n");
printf("===============员工信息排序==========\n");
printf("请选择:");
scanf("%d",&choice);
if (0 == choice)
{
break;
}
switch (choice)
{
case 1:
SortNum(plist);
break;
case 2:
SortAge(plist);
break;
default:
printf("输入错误!\n");
}
}
}
int main()
{
List *plist;
plist = InitList();
while(1)
{
int choice = 0;
printf("===============主菜单===============\n");
printf("= 1.更新员工信息 =\n");
printf("= 2.查询员工信息 =\n");
printf("= 3.排序员工信息 =\n");
printf("= 4.遍历员工信息 =\n");
printf("= 5.清空员工信息 =\n");
printf("= 0. 退出 =\n");
printf("===============主菜单===============\n");
printf("请选择想要的操作序号:");
scanf("%d",&choice);
if (0 == choice)
{
printf("欢迎下次使用!\n");
break;
}
switch (choice)
{
case 1:
UpdateInfo(plist);
break;
case 2:
FindInfo(plist);
break;
case 3:
SortInfo(plist);
break;
case 4:
travel(plist);
break;
case 5:
destroy(plist);
break;
default:
printf("输入错误!");
}
}
return 0;
}
8、Makefile
OBJ = main.o localhandle.o List.o FileManagement.o
main:$(OBJ)
gcc -g -o main $(OBJ)
List.o:List.c List.h
gcc -c List.c
FileManagement.o:FileManagement.c FileManagement.h
gcc -c FileManagement.c
localhandle.o:localhandle.c localhandle.h
gcc -c localhandle.c
.PHONY:clear
clear:
rm main $(OBJ)
9、编译
直接make就行,可以生成可执行文件main。Makefile里加了GDB调试的编译参数,可以使用GDB调试。
三、Server和Client模式
一、Server端
1、List.h
#ifndef LIST_H
#define LIST_H
#define TO_FILE "/home/liuyin/test/project/test/server/list.data"
typedef struct Node* PNode;
typedef PNode Position;
/*节点结构*/
typedef struct Node
{
//int data; //数据域
char num[20]; //work number
char name[20]; //name
char sex[20]; //sex
char age[20]; //age
char tel[20]; //phone
PNode pre; //前驱指针
PNode next; //后继指针
}Node;
typedef struct
{
int size;
PNode head;
PNode tail;
}List;
//PNode InitList(List *plist);
//分配节点,并返回节点地址
Position MakeNode();
struct List *Create();
//构造一个空的双向链表
List *InitList();
void clearlist(List *plist);
void clearlist1(List *plist);
//清空链表
void destroylist(List *plist);
//返回头节点地址
Position GetHead(List *plist);
//返回尾节点地址
Position GetTail(List *plist);
//返回链表大小
int GetSize(List *plist);
//判断链表是否为空
int IsEmpty(List *plist);
//删除头节点
void DelFirst(List *plist);
//删除尾节点
void DelEnd(List *plist);
//删除中间节点
void DelMind(List *plist);
#endif
2、FileManagement.h
#ifndef FILEMANAGEMENT_H
#define FILEMANAGEMENT_H
#include "List.h"
//写入info文件
void WriteFile(List *plist);
//读取info文件
void ReadFile(List *plist);
#endif
3、Management.h
Server端收到请求后调用的内部函数。
#ifndef MANAGEMENT_H
#define MANAGEMENT_H
#include "List.h"
#include "Socket.h"
//一、员工信息更新,按0返回
//1.新增员工资料
void Add(List *plist,Msg *msg,int clientfd);
//2.删除员工资料,按工号删除
void DelNum(List *plist,Msg *msg,int clientfd);
//3.修改员工资料
void ChangeNum(List *plist,Msg *msg,int clientfd);
//二、员工信息查询
//按工号删除和修改用的查找
PNode FindNum1(List *plist,char *num);
//1.姓名查找
PNode FindName(List *plist,Msg *msg,int clientfd);
//2.工号查找
PNode FindNum(List *plist,Msg *msg,int clientfd);
//3.年龄查找(大于多少,小于多少)
PNode FindAge(List *plist,Msg *msg,int clientfd);
//三、员工信息排序
//交换节点
void swap(List *plist,PNode s1,PNode s2);
//void SortAge(List *plist,PNode phead,PNode ptail,int n);
//1.按年龄排序
void SortAge(List *plist,Msg *msg,int clientfd);
//2.按工号排序
void SortNum(List *plist,Msg *msg,int clientfd);
//遍历员工信息
void travel(List *plist,Msg *msg,int clientfd);
//清空员工信息
void destroy(List *plist,Msg *msg,int clientfd);
#endif
4、HandleRequest.h
Server端收到Client端的消息后,进入此处理函数,根据类型调用不同的函数。
#ifndef HANDLEREQUEST_H
#define HANDLEREQUEST_H
#include "Socket.h"
void HandleRequest(void *arg);
#endif
5、Socket.h
#ifndef SOCKET_H
#define SOCKET_H
#define TO_FILE "/home/liuyin/test/project/test/server/list.data"
#define MSG_MAX 100
#define PORT 8000
#define ADDRESS "192.168.226.128"
//#define ADDRESS "172.30.51.44"
#define BACKLOG 100
#define MAXLINE 1024
enum MsgType
{
ADD_INFO = 1,
UPDATE_INFO,
DELETE_INFO,
FIND_NAME,
FIND_NUM,
FIND_AGE,
SORT_NUM,
SORT_AGE,
TRAVEL,
DESTROY
};
typedef struct
{
int count;
char type;//消息类型
char data[100];//消息内容
char num[20]; //work number
char name[20]; //name
char sex[20]; //sex
char age[20]; //age
char tel[20]; //phone
}Msg;
#endif
6、List.c
#include "List.h"
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
//分配节点,并返回节点地址
Position MakeNode()
{
PNode p = NULL;
p = (PNode)malloc(sizeof(Node));
if (NULL != p)
{
p->pre = NULL;
p->next = NULL;
}
return p;
}
//构造一个空的双向链表
List *InitList()
{
List *plist = (List *)malloc(sizeof(List));
PNode head = MakeNode();
if (NULL != plist)
{
if (NULL != head)
{
plist->head = head;
plist->tail = head;
plist->size = 0;
}
else
{
return NULL;
}
}
return plist;
}
void clearlist(List *plist)
{
if (NULL == plist->head)
{
return;
}
PNode p = plist->head->next;
while (NULL != p)
{
PNode temp = p->next;
free(p);
p = temp;
}
plist->head = NULL;
}
void clearlist1(List *plist)
{
PNode p = plist->head->next;
int size = plist->size-1;
PNode temp = NULL;
while (size--)
{
temp = p;
p = p->next;
free(temp);
}
plist->size = 1;
}
//清空链表
void destroylist(List *plist)
{
PNode p = plist->head->next;
int size = plist->size;
PNode temp = NULL;
while (size--)
{
//PNode temp = p;
temp = p;
p = p->next;
free(temp);
}
plist->size = 0;
}
//返回头节点地址
Position GetHead(List *plist)
{
return plist->head;
}
//返回尾节点地址
Position GetTail(List *plist)
{
return plist->tail;
}
//返回链表大小
int GetSize(List *plist)
{
return plist->size;
}
//判断链表是否为空
int IsEmpty(List *plist)
{
if(GetSize(plist) == 0 && GetTail(plist) == GetHead(plist))
{
return 1;
}
else
{
return 0;
}
}
7、FileManagement.c
#include "FileManagement.h"
#include "Management.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//写入info文件
void WriteFile(List *plist)
{
FILE * fp = fopen(TO_FILE,"w");
if (NULL == fp)
{
printf("File Not Found!\n");
exit(1);
}
int size = plist->size;
PNode q = plist->head->next;
while (size--)
{
fprintf(fp," %s\t %s\t %s\t %s\t %s\t\n",q->num,q->name,q->sex,q->age,q->tel);
q = q->next;
}
fclose(fp);
}
//读取info文件
void ReadFile(List *plist)
{
destroylist(plist);
FILE *fp = fopen(TO_FILE,"r");
if (NULL == fp)
{
printf("FILE NOT FOUND!");
exit(1);
}
while (0 == feof(fp))
{
PNode q = MakeNode();
fscanf(fp," %s\t %s\t %s\t %s\t %s\t ",q->num,q->name,q->sex,q->age,q->tel);
if (0 == strcmp(q->num," "))
{
break;
}
if (0 == plist->size)
{
plist->head->next = q;
}
else
{
plist->tail->next = q;
q->pre = plist->tail;
}
plist->tail = q;
plist->size++;
}
fclose(fp);
}
8、Management.c
#include "Management.h"
#include "FileManagement.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// 一、员工信息更新,按0返回
// 1.新增员工资料
void Add(List *plist,Msg *msg,int clientfd)
{
//ReadFile(plist);
//printf("提示:输入0返回更新员工信息菜单!\n");
PNode p = MakeNode();
strcpy(p->num,msg[0].num);
strcpy(p->name,msg[0].name);
strcpy(p->sex,msg[0].sex);
strcpy(p->age,msg[0].age);
strcpy(p->tel,msg[0].tel);
PNode q = FindNum1(plist,p->num);
if (NULL != q)
{
memset(msg,0,sizeof(Msg));
strcpy(msg[0].data,"工号已存在!");
strcpy(msg[0].num,"0");
write(clientfd,msg,sizeof(Msg));
return;
}
if (0 == plist->size)//空链表
{
plist->head = p;
}
else
{
plist->tail->next = p;
p->pre = plist->tail;
}
plist->tail = p;
plist->size++;
strcpy(msg[0].data,"一条员工信息已添加!");
write(clientfd,msg,sizeof(Msg));
WriteFile(plist);
}
//2.删除员工资料,按姓名删除
//按工号删除和修改用的查找
PNode FindNum1(List *plist,char *num)
{
ReadFile(plist);
PNode p = plist->head->next;
int size = plist->size;
while (size--)
{
if(0 == strcmp(num,p->num))
{
return p;
break;
}
if (NULL != p->next)
{
p = p->next;
}
}
if (p == plist->tail && strcmp(num,p->num) != 0)
{
return NULL;
}
}
//按工号删除
void DelNum(List *plist,Msg *msg,int clientfd)
{
PNode p = FindNum1(plist,msg[0].num);
if (NULL == p)
{
memset(msg,0,sizeof(Msg));
strcpy(msg[0].data,"无此员工信息!");
strcpy(msg[0].num,"0");
write(clientfd,msg,sizeof(Msg));
//printf("无此员工信息!\n");
return;
}
memset(msg,0,sizeof(Msg));
strcpy(msg[0].data,"该员工信息如下:");
strcpy(msg[0].num,p->num);
strcpy(msg[0].name,p->name);
strcpy(msg[0].sex,p->sex);
strcpy(msg[0].age,p->age);
strcpy(msg[0].tel,p->tel);
write(clientfd,msg,sizeof(Msg));
//删除头节点
if (p == plist->head->next)
{
plist->head->next = p->next;
}
//删除尾节点
else if (p == plist->tail)
{
plist->tail = plist->tail->pre;
}
//删除中间节点
else
{
p->pre->next = p->next;
p->next->pre = p->pre;
//p->pre->next = p->next;
}
plist->size--;
free(p);
WriteFile(plist);
//printf("删除成功!\n");
return;
}
//3.修改员工资料
void ChangeNum(List *plist,Msg *msg,int clientfd)
{
PNode p = FindNum1(plist,msg[0].num);
if (NULL == p)
{
memset(msg,0,sizeof(Msg));
strcpy(msg[0].data,"无此员工信息!");
strcpy(msg[0].num,"0");
write(clientfd,msg,sizeof(Msg));
//printf("无此员工信息!\n");
return;
}
memset(msg,0,sizeof(Msg));
strcpy(msg[0].data,"该员工信息如下:");
strcpy(msg[0].num,p->num);
strcpy(msg[0].name,p->name);
strcpy(msg[0].sex,p->sex);
strcpy(msg[0].age,p->age);
strcpy(msg[0].tel,p->tel);
write(clientfd,msg,sizeof(Msg));
memset(msg,0,sizeof(Msg));
read(clientfd,msg,sizeof(Msg));
strcpy(p->num,msg[0].num);
strcpy(p->name,msg[0].name);
strcpy(p->sex,msg[0].sex);
strcpy(p->age,msg[0].age);
strcpy(p->tel,msg[0].tel);
WriteFile(plist);
return;
}
//二、员工信息查询
//1.姓名查找
PNode FindName(List *plist,Msg *msg,int clientfd)
{
ReadFile(plist);
PNode p = plist->head->next;
int size = plist->size;
int i = 1;
while (size--)
{
if(0 == strcmp(p->name,msg[0].name))
{
strcpy(msg[i].num,p->num);
strcpy(msg[i].name,p->name);
strcpy(msg[i].sex,p->sex);
strcpy(msg[i].age,p->age);
strcpy(msg[i].tel,p->tel);
i++;
msg[0].count = i-1;
}
p = p->next;
}
//printf("msg[0].count=%d\n",msg[0].count);
if (1 == i)
{
strcpy(msg[0].num,"0");
strcpy(msg[0].data,"无此员工信息!");
write(clientfd,msg,sizeof(Msg));
}
else
{
strcpy(msg[0].data,"员工信息显示如下:");
write(clientfd,msg,sizeof(Msg[MSG_MAX]));
}
}
//2.工号查找
PNode FindNum(List *plist,Msg *msg,int clientfd)
{
ReadFile(plist);
PNode p = plist->head->next;
int size = plist->size;
int i = 1;
//printf("%s\n",msg[0].num);
while (size--)
{
if(0 == strcmp(p->num,msg[0].num))
{
//memset(msg,0,sizeof(Msg));
strcpy(msg[0].num,p->num);
strcpy(msg[0].name,p->name);
strcpy(msg[0].sex,p->sex);
strcpy(msg[0].age,p->age);
strcpy(msg[0].tel,p->tel);
strcpy(msg[0].data,"员工信息显示如下:");
write(clientfd,msg,sizeof(Msg));
// fprintf(fp," %s\t %s\t %s\t %s\t %s\t\n",p->num,p->name,p->sex,p->age,p->tel);
break;
}
p = p->next;
if (size <= 0)
{
memset(msg,0,sizeof(Msg));
strcpy(msg[0].data,"无此员工信息!");
strcpy(msg[0].num,"0");
write(clientfd,msg,sizeof(Msg));
}
}
}
//3.年龄查找(大于多少,小于多少)
PNode FindAge(List *plist,Msg *msg,int clientfd)
{
ReadFile(plist);
PNode p = plist->head->next;
int size = plist->size;
int i = 1;
if (0 == strcmp(msg[0].data,"1"))
{
while (size--)
{
if (strcmp(msg[0].age,p->age) >= 0)
{
strcpy(msg[i].num,p->num);
strcpy(msg[i].name,p->name);
strcpy(msg[i].sex,p->sex);
strcpy(msg[i].age,p->age);
strcpy(msg[i].tel,p->tel);
i++;
msg[0].count = i-1;
//fprintf(fp," %s\t %s\t %s\t %s\t %s\t\n",p->num,p->name,p->sex,p->age,p->tel);
}
p = p->next;
}
}
else if (0 == strcmp(msg[0].data,"2"))
{
while (size--)
{
if (strcmp(msg[0].age,p->age) <= 0)
{
strcpy(msg[i].num,p->num);
strcpy(msg[i].name,p->name);
strcpy(msg[i].sex,p->sex);
strcpy(msg[i].age,p->age);
strcpy(msg[i].tel,p->tel);
i++;
msg[0].count = i;
//fprintf(fp," %s\t %s\t %s\t %s\t %s\t\n",p->num,p->name,p->sex,p->age,p->tel);
}
p = p->next;
}
}
if (1 == i)
{
strcpy(msg[0].num,"0");
strcpy(msg[0].data,"无此员工信息!");
write(clientfd,msg,sizeof(Msg));
}
//memset(msg,0,sizeof(Msg));
strcpy(msg[0].data,"员工信息显示如下:");
write(clientfd,msg,sizeof(Msg[MSG_MAX]));
}
//三、员工信息排序
//1.按年龄排序
void SortAge(List *plist,Msg *msg,int clientfd)
{
loop1:
ReadFile(plist);
int size = plist->size;
if (0 == size)
{
memset(msg,0,sizeof(Msg));
strcpy(msg[0].data,"员工列表为空!");
strcpy(msg[0].num,"0");
write(clientfd,msg,sizeof(Msg));
return;
}
PNode p = plist->head->next;
PNode q = NULL,temp = NULL;
memset(msg,0,sizeof(Msg));
PNode tp = plist->head->next;
PNode mov = tp->next;
PNode phead = plist->head;
if (1 == size)
{
strcpy(msg[0].data,"员工信息显示如下:");
}
else if (p && size >= 2)
{
if ((size >= 2) && strcmp(tp->age,mov->age) > 0)
{
if (mov->next)
{
mov->pre->next = mov->next;
mov->next->pre = mov->pre;
mov->next = phead->next;
phead->next->pre = mov;
mov->pre = phead;
phead->next = mov;
}
else
{
mov->pre->next = NULL;
mov->next = phead->next;
phead->next->pre = mov;
mov->pre = phead;
phead->next = mov;
}
}
for (p = p->next;p;p = p->next)//从第二个开始,第一个默认有序
{
temp = p;
for (q = p->pre;q != plist->head->next;q = q->pre)//q从p的前一节点开始往前
{
if (strcmp(q->age,temp->age) <= 0)//升序
{
break;
}
}
if (q->next != p)//如果q有前移,插入temp
{
if (temp->next)//temp不为最后一个节点
{
//temp前后互指,分离temp
temp->pre->next = temp->next;
temp->next->pre = temp->pre;
//插入temp
temp->next = q->next;
q->next->pre = temp;
temp->pre = q;
q->next = temp;
}
else//temp是最后一个节点
{
temp->pre->next = NULL;//temp前一节点的next指为NULL
//插入temp
temp->next = q->next;
q->next->pre = temp;
temp->pre = q;
q->next = temp;
}
}
}
strcpy(msg[0].data,"员工信息显示如下:");
}
//write(clientfd,msg,sizeof(Msg));
WriteFile(plist);
PNode cp = plist->head->next;
PNode cp1 = cp ->next;
if ((size >= 2) && strcmp(cp->age,cp1->age) > 0)
{
goto loop1;
}
write(clientfd,msg,sizeof(Msg));
}
//2.按工号排序
void SortNum(List *plist,Msg *msg,int clientfd)
{
loop2:
ReadFile(plist);
int size = plist->size;
if (0 == size)
{
memset(msg,0,sizeof(Msg));
strcpy(msg[0].data,"员工列表为空!");
strcpy(msg[0].num,"0");
write(clientfd,msg,sizeof(Msg));
return;
}
PNode p = plist->head->next;
PNode q = NULL,temp = NULL;
memset(msg,0,sizeof(Msg));
PNode tp = plist->head->next;
PNode mov = tp->next;
PNode phead = plist->head;
if (1 == size)
{
strcpy(msg[0].data,"员工信息显示如下:");
}
else if(p && size >= 2)
{
if (strcmp(tp->num,mov->num) > 0)
{
if (mov->next)
{
mov->pre->next = mov->next;
mov->next->pre = mov->pre;
mov->next = phead->next;
phead->next->pre = mov;
mov->pre = phead;
phead->next = mov;
}
else
{
mov->pre->next = NULL;
mov->next = phead->next;
phead->next->pre = mov;
mov->pre = phead;
phead->next = mov;
}
}
for (p = p->next;p;p = p->next)//从第二个开始,第一个默认有序
{
temp = p;
for (q = p->pre;q != plist->head->next;q = q->pre)//q从p的前一节点开始往前
{
if (strcmp(q->num,temp->num) <= 0)//升序
{
break;
}
}
if (q->next != p)//如果q有前移,插入temp
{
if (temp->next)//temp不为最后一个节点
{
//temp前后互指,分离temp
temp->pre->next = temp->next;
temp->next->pre = temp->pre;
//插入temp
temp->next = q->next;
q->next->pre = temp;
temp->pre = q;
q->next = temp;
}
else//temp是最后一个节点
{
temp->pre->next = NULL;//temp前一节点的next指为NULL
//插入temp
temp->next = q->next;
q->next->pre = temp;
temp->pre = q;
q->next = temp;
}
}
}
strcpy(msg[0].data,"员工信息显示如下:");
}
//write(clientfd,msg,sizeof(Msg));
WriteFile(plist);
PNode cp = plist->head->next;
PNode cp1 = cp ->next;
if ((size >= 2) && strcmp(cp->num,cp1->num) > 0)
{
goto loop2;
}
write(clientfd,msg,sizeof(Msg));
}
//遍历员工信息
void travel(List *plist,Msg *msg,int clientfd)
{
ReadFile(plist);
int size = plist->size;
PNode p = plist->head->next;
int i = 0;
if (0 == plist->size)
{
memset(msg,0,sizeof(Msg));
strcpy(msg[0].data,"员工列表为空!");
strcpy(msg[0].num,"0");
write(clientfd,msg,sizeof(Msg));
return;
}
else
{
while (size--)
{
strcpy(msg[i].num,p->num);
strcpy(msg[i].name,p->name);
strcpy(msg[i].sex,p->sex);
strcpy(msg[i].age,p->age);
strcpy(msg[i].tel,p->tel);
msg[0].count = i;
i++;
p = p->next;
}
strcpy(msg[0].data,"员工信息显示如下:");
write(clientfd,msg,sizeof(Msg[MSG_MAX]));
}
}
//清空员工信息
void destroy(List *plist,Msg *msg,int clientfd)
{
destroylist(plist);
WriteFile(plist);
memset(msg,0,sizeof(Msg[MSG_MAX]));
strcpy(msg[0].data,"员工信息已全部清除!");
write(clientfd,msg,sizeof(Msg[MSG_MAX]));
}
9、HandleRequest.c
#include "HandleRequest.h"
#include "List.h"
#include <stdio.h>
#include <string.h>
void HandleRequest(void *arg)
{
printf("This is HandleRequesat!\n");
List *plist;
plist =InitList();
Msg msg[MSG_MAX];
unsigned int clientfd = *(unsigned int *)arg;
while (1)
{
memset(msg,0,sizeof(Msg[MSG_MAX]));
read(clientfd,msg,sizeof(Msg[MSG_MAX]));
if (0 == msg[0].type)
{
break;
}
switch (msg[0].type)
{
case ADD_INFO:
Add(plist,msg,clientfd);
break;
case UPDATE_INFO:
ChangeNum(plist,msg,clientfd);
break;
case DELETE_INFO:
DelNum(plist,msg,clientfd);
break;
case FIND_NAME:
FindName(plist,msg,clientfd);
break;
case FIND_NUM:
FindNum(plist,msg,clientfd);
break;
case FIND_AGE:
FindAge(plist,msg,clientfd);
break;
case SORT_NUM:
SortNum(plist,msg,clientfd);
//SortNum(plist,msg,clientfd);
break;
case SORT_AGE:
SortAge(plist,msg,clientfd);
//SortAge(plist,msg,clientfd);
break;
case TRAVEL:
travel(plist,msg,clientfd);
break;
case DESTROY:
destroy(plist,msg,clientfd);
break;
default:
printf("输入错误!\n");
}
}
}
10、Socket.c
#include "Management.h"
#include "HandleRequest.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <errno.h>
Msg msg;
//线程1处理函数
void *Process1(void *arg)
{
printf("This is Process1!\n");
HandleRequest(arg);
}
int main()
{
int ret = -1;
int sockfd = -1; //定义socket网络文件描述符
int clientfd = -1; //定义accept网络文件描述符
pthread_t th = -1; //定义一个多线程的创建句柄
struct sockaddr_in servaddr = {0};//服务器对应套接字地址
struct sockaddr_in cletaddr = {0};//客户端
socklen_t address_len = 0; //客户端长度
unsigned int addrlen = sizeof(struct sockaddr_in);
//套接字
sockfd = socket(AF_INET,SOCK_STREAM,0);
if (sockfd < 0)
{
perror("create socket error!\n");
exit(1);
}
memset(&servaddr,0,sizeof(addrlen));
servaddr.sin_family = AF_INET;//定义servaddr地址组IPv4
servaddr.sin_port = htons(PORT);//设置监听端口
servaddr.sin_addr.s_addr = inet_addr(ADDRESS);//定义sercaddr的address
//servaddr.sin_addr.s_addr = INADDR_ANY;监听主机所有IP
//由TCP套接字状态TIME_WAIT引起在结束本次会话后close立刻开启下次会话会Bind失败。
//该状态在套接字关闭后约保留 2 到 4 分钟。在 TIME_WAIT 状态退出之后,套接字被删除,该地址才能被重新绑定而不出问题。
//因此下面两句话的加入可以解决这个问题
int opt = 1;
ret = setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));
ret = bind(sockfd,(const struct sockaddr *)&servaddr,sizeof(servaddr));
if (ret < 0)
{
perror("Bind error!\n");
exit(1);
}
ret = listen(sockfd,BACKLOG);
if (ret < 0)
{
perror("Listen error!\n");
exit(1);
}
printf("等待客户端连接......\n");
memset(&cletaddr,0,addrlen);
while (1)
{
//accept阻塞等待客户端连接
clientfd = accept(sockfd,(struct sockaddr *)&cletaddr,&addrlen);
if (clientfd < 0)
{
perror("Accept error!\n");
exit(1);
}
printf("listen client success!clientfd=%d\n",clientfd);
printf("client port=%d\n",ntohs(cletaddr.sin_port));
printf("client IP=%s\n",inet_ntoa(cletaddr.sin_addr));
if (pthread_create(&th,NULL,Process1,&clientfd) == -1)
{
perror("pthread_create error!\n");
exit(1);
}
}
return 0;
}
11、Makefile
同样加入了GDB调试参数。
OBJ = List.o FileManagement.o Management.o Socket.o HandleRequest.o
server:$(OBJ)
gcc -g -o server $(OBJ) -lpthread
List.o:List.c List.h
gcc -c List.c
FileManagement.o:FileManagement.c FileManagement.h
gcc -c FileManagement.c
Management.o:Management.c Management.h
gcc -c Management.c
Socket.o:Socket.c Socket.h
gcc -c Socket.c
HandleRequest.o:HandleRequest.c HandleRequest.h
gcc -c HandleRequest.c
.PHONY:clean
clean:
rm server $(OBJ)
二、Client端
1、Socket.h
#ifndef SOCKET_H
#define SOCKET_H
//#define TO_FILE "/home/liuyin/test/project/test/server/list.data"
#define MSG_MAX 100
#define PORT 8000
#define ADDRESS "192.168.226.128"
//#define ADDRESS "172.30.51.44"
//#define ADDRESS "172.30.50.255"
#define BACKLOG 100
#define MAXLINE 1024
enum MsgType//Client端active的枚举
{
ADD_INFO = 1,
UPDATE_INFO,
DELETE_INFO,
FIND_NAME,
FIND_NUM,
FIND_AGE,
SORT_NUM,
SORT_AGE,
TRAVEL,
DESTROY
};
typedef struct
{
int count;
char type;//消息类型
char data[100];//消息内容
char num[20]; //work number
char name[20]; //name
char sex[20]; //sex
char age[20]; //age
char tel[20]; //phone
}Msg;
#endif
2、Request.h
Client端定义的函数接口。
#ifndef REQUEST_H
#define REQUEST_H
#include "/home/liuyin/test/server/Socket.h"
static void Read_Msg_File(Msg msg);
//目录界面
void Send_ClientMenu(void *arg);
void Recv_ClientMenu(int serverfd);
//新增员工信息
void Add_Info(int serverfd,Msg *msg);
//修改员工信息
void Change_Info(int serverfd,Msg *msg);
//删除员工信息
void Del_Info(int serverfd,Msg *msg);
//按姓名查找
void Find_Name(int serverfd,Msg *msg);
//按工号查找
void Find_Num(int serverfd,Msg *msg);
//按年龄查找
void Find_Age(int serverfd,Msg *msg);
//按工号排序
void Sort_Num(int serverfd,Msg *msg,int Istravel);
//按年龄排序
void Sort_Age(int serverfd,Msg *msg);
//遍历员工信息
void Travel_Info(int serverfd,Msg *msg);
//清空员工信息
void Destroy_Info(int serverfd,Msg *msg);
#endif
3、Client(Client端的main函数)
#include "Request.h"
#include "help.h"
#include <stdio.h>
#include <string.h>
//更新员工信息
static void UpdateInfo(int serverfd,Msg *msg)
{
int choice = 0;
while (1)
{
printf("=============更新员工信息============\n");
printf("= 1.新增员工信息 =\n");
printf("= 2.修改员工信息 =\n");
printf("= 3.删除员工信息 =\n");
printf("= 4. 帮助信息 =\n");
printf("= 0.返回主菜单 =\n");
printf("=============更新员工信息============\n");
printf("请选择:");
scanf("%d",&choice);
if (0 == choice)
{
break;
}
switch (choice)
{
case 1:
Add_Info(serverfd,msg);
Sort_Num(serverfd,msg,0);
break;
case 2:
Change_Info(serverfd,msg);
break;
case 3:
Del_Info(serverfd,msg);
break;
case 4:
help(2);
break;
default:
printf("输入错误!\n");
}
}
}
//查询员工信息
static void FindInfo(int serverfd,Msg *msg)
{
int choice = 0;
while (1)
{
printf("==============查询员工信息==========\n");
printf("= 1.按姓名查找 =\n");
printf("= 2.按工号查找 =\n");
printf("= 3.按年龄查找 =\n");
printf("= 4. 帮助信息 =\n");
printf("= 0.返回主菜单 =\n");
printf("==============查询员工信息==========\n");
printf("请选择:");
scanf("%d",&choice);
if (0 == choice)
{
break;
}
switch (choice)
{
case 1:
Find_Name(serverfd,msg);
break;
case 2:
Find_Num(serverfd,msg);
break;
case 3:
Find_Age(serverfd,msg);
break;
case 4:
help(3);
break;
default:
printf("输入错误!\n");
}
}
}
//员工信息排序
static void SortInfo(int serverfd,Msg *msg)
{
int choice = 0;
while (1)
{
printf("===============员工信息排序==========\n");
printf("= 1.按工号排序 =\n");
printf("= 2.按年龄排序 =\n");
printf("= 3. 帮助信息 =\n");
printf("= 0. 返回主菜单 =\n");
printf("===============员工信息排序==========\n");
printf("请选择:");
scanf("%d",&choice);
if (0 == choice)
{
break;
}
switch (choice)
{
case 1:
Sort_Num(serverfd,msg,1);
break;
case 2:
Sort_Age(serverfd,msg);
break;
case 3:
help(4);
break;
default:
printf("输入错误!\n");
}
}
}
void Send_ClientMenu(void *arg)
{
unsigned int serverfd = *(unsigned int*)arg;
Msg msg[MSG_MAX];
while (1)
{
int choice = 0;
printf("===============主菜单===============\n");
printf("= 1.更新员工信息 =\n");
printf("= 2.查询员工信息 =\n");
printf("= 3.排序员工信息 =\n");
printf("= 4.遍历员工信息 =\n");
printf("= 5.清空员工信息 =\n");
printf("= 6. 帮助信息 =\n");
printf("= 0. 退出 =\n");
printf("===============主菜单===============\n");
printf("请选择想要的操作序号:");
scanf("%d",&choice);
if (0 == choice)
{
printf("欢迎下次使用!\n");
break;
}
switch (choice)
{
case 1:
UpdateInfo(serverfd,msg);
break;
case 2:
FindInfo(serverfd,msg);
break;
case 3:
SortInfo(serverfd,msg);
break;
case 4:
Travel_Info(serverfd,msg);
break;
case 5:
Destroy_Info(serverfd,msg);
break;
case 6:
help(1);
break;
default:
printf("输入错误!\n");
}
}
}
4、help.h
其实这个帮助信息我也不知道怎么写,只能写一个最笨的也是最简单的帮助信息了,虽然没什么用。
#ifndef HELP_H
#define HELP_H
void help(int n);
#endif
5、help.c
#include "help.h"
#include <stdio.h>
void help(int n)
{
switch (n)
{
case 1:
printf("1 --进入更新菜单,可以新增、修改和删除员工信息\n");
printf("2 --进入查询菜单,可以按姓名、工号查找,按年龄范围查找\n");
printf("3 --进入排序菜单,可以按工号和年龄排序\n");
printf("4 --显示所有的员工信息\n");
printf("5 --清空所有员工信息\n");
printf("6 --显示帮助信息\n");
printf("0 --退出系统\n");
break;
case 2:
printf("1 --增加新的员工信息,按提示输入员工信息,按0返回\n");
printf("2 --修改员工信息,输入需要修改的员工工号,若有,则按提示输入新的信息\n");
printf("3 --删除员工信息,输入想要删除的员工工号,若有则显示删除成功\n");
printf("4 --显示帮助信息\n");
printf("0 --返回主菜单\n");
break;
case 3:
printf("1 --按要求输入姓名,有则返回该员工信息(可能不止一名员工)\n");
printf("2 --按要求输入工号,有则返回该员工信息\n");
printf("3 --按要求输入年龄界限,选择大于此界限还是小于此界限,返回范围内的员工信息\n");
printf("4 --显示帮助信息\n");
printf("0 --返回主菜单\n");
break;
case 4:
printf("1 --按员工工号进行升序排序\n");
printf("2 --按员工年龄进行升序排序\n");
printf("3 --显示帮助信息\n");
printf("0 --返回主菜单\n");
break;
}
}
6、Socket.c
#include "Request.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <pthread.h>
#include<errno.h>
#include <unistd.h>
void *Client_fun1(void *arg)
{
printf("This is Client_fun1!\n");
Send_ClientMenu(arg);
}
// void *Client_fun2(void *arg)
// {
// printf("This is Client_fun2!\n");
// void Recv_ClientMenu(int serverfd);
// }
int main()
{
struct sockaddr_in servaddr;
unsigned int addrlen = sizeof(struct sockaddr_in);
int sockfd = -1;
sockfd = socket(AF_INET,SOCK_STREAM,0);
if (sockfd == -1)
{
perror("Client create sockfd error!\n");
exit(1);
}
memset(&servaddr,0,addrlen);
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(PORT);
servaddr.sin_addr.s_addr = inet_addr(ADDRESS);
if (connect(sockfd,(struct sockaddr *)&servaddr,addrlen) == -1)
{
perror("Client bind error!\n");
exit(1);
}
pthread_t pid1;
if (pthread_create(&pid1,NULL,Client_fun1,&sockfd) == -1)
{
perror("Client pthread_create1 error!\n");
exit(1);
}
// if (pthread_create(&pid2,NULL,Client_fun2,&sockfd) == -1)
// {
// perror("Client pthread_create2 error!\n");
// exit(1);
// }
pthread_join(pid1,NULL);
//pthread_join(pid2,NULL);
return 0;
}
7、Request.c
#include "Request.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static int inputmsg(char *msg)
{
int n = strcmp(msg,"0");
return n;
}
//新增员工信息
void Add_Info(int serverfd,Msg *msg)
{
while (1)
{
msg[0].type = ADD_INFO;
printf("提示:输入0返回更新员工信息菜单!\n");
printf("请输入员工工号:\n");
scanf("%s",msg[0].num);
if (0 == inputmsg(msg[0].num))
{
break;
}
printf("请输入员工姓名:\n");
scanf("%s",msg[0].name);
if ( 0 == inputmsg(msg[0].name))
{
break;
}
printf("请输入员工性别:\n");
scanf("%s",msg[0].sex);
if ( 0 == inputmsg(msg[0].sex))
{
break;
}
printf("请输入员工年龄:\n");
scanf("%s",msg[0].age);
if ( 0 == inputmsg(msg[0].age))
{
break;
}
printf("请输入员工电话:\n");
scanf("%s",msg[0].tel);
if ( 0 == inputmsg(msg[0].tel))
{
break;
}
write(serverfd,msg,sizeof(Msg));
memset(msg,0,sizeof(Msg));
read(serverfd,msg,sizeof(Msg));
if (0 == inputmsg(msg[0].num))
{
printf("%s\n",msg[0].data);
}
else
{
printf("%s\n",msg[0].data);
}
}
}
//修改员工信息
void Change_Info(int serverfd,Msg *msg)
{
memset(msg,0,sizeof(Msg));
msg[0].type = UPDATE_INFO;
printf("提示:输入0返回更新员工信息菜单!\n");
printf("请输入你要修改的员工工号:");
scanf("%s",msg[0].num);
if (0 == inputmsg(msg[0].num))
{
return;
}
//printf("%s\n",msg[0].num);
write(serverfd,msg,sizeof(Msg));
memset(msg,0,sizeof(Msg));
read(serverfd,msg,sizeof(Msg));
if (0 == inputmsg(msg[0].num))
{
printf("%s\n",msg[0].data);
return;
}
else
{
printf("%s\n",msg[0].data);
printf("\n工号 姓名 性别 年龄 电话\n");
printf("\n %s\t %s\t %s\t %s\t %s\t\n",msg[0].num,msg[0].name,msg[0].sex,msg[0].age,msg[0].tel);
memset(msg,0,sizeof(Msg));
printf("请输入新工号:");
scanf("%s",msg[0].num);
printf("请输入新姓名:");
scanf("%s",msg[0].name);
printf("请输入新性别:");
scanf("%s",msg[0].sex);
printf("请输入新年龄:");
scanf("%s",msg[0].age);
printf("请输入新电话:");
scanf("%s",msg[0].tel);
write(serverfd,msg,sizeof(Msg));
printf("员工信息修改成功!\n");
}
}
//删除员工信息
void Del_Info(int serverfd,Msg *msg)
{
memset(msg,0,sizeof(Msg));
msg[0].type = DELETE_INFO;
printf("提示:输入0返回更新员工信息菜单!\n");
printf("请输入你要删除的员工工号:");
scanf("%s",msg[0].num);
if (0 == inputmsg(msg[0].num))
{
return;
}
write(serverfd,msg,sizeof(Msg));
memset(msg,0,sizeof(Msg));
read(serverfd,msg,sizeof(Msg));
if (0 == inputmsg(msg[0].num))
{
printf("%s\n",msg[0].data);
return;
}
else
{
printf("删除成功!\n");
}
}
//按姓名查找
void Find_Name(int serverfd,Msg *msg)
{
memset(msg,0,sizeof(Msg));
msg[0].type = FIND_NAME;
printf("提示:输入0返回更新员工信息菜单!\n");
printf("请输入你要查找的员工姓名:");
scanf("%s",msg[0].name);
if (0 == inputmsg(msg[0].name))
{
return;
}
write(serverfd,msg,sizeof(Msg));
memset(msg,0,sizeof(Msg));
int n = read(serverfd,msg,sizeof(Msg[MSG_MAX]));
//printf("msg[0].count=%d\n",msg[0].count);
if (0 == inputmsg(msg[0].num))
{
printf("%s\n",msg[0].data);
return;
}
else
{
printf("\n工号 姓名 性别 年龄 电话\n");
int i = 1;
for (;i <= msg[0].count;i++)
{
printf("\n %s\t %s\t %s\t %s\t %s\t\n",msg[i].num,msg[i].name,msg[i].sex,msg[i].age,msg[i].tel);
}
}
}
//按工号查找
void Find_Num(int serverfd,Msg *msg)
{
memset(msg,0,sizeof(Msg));
msg[0].type = FIND_NUM;
printf("提示:输入0返回更新员工信息菜单!\n");
printf("请输入你要查找的员工工号:");
scanf("%s",msg[0].num);
if (0 == inputmsg(msg[0].num))
{
return;
}
write(serverfd,msg,sizeof(Msg));
//printf("%s\n",msg.num);
memset(msg,0,sizeof(Msg));
read(serverfd,msg,sizeof(Msg));
if (0 == inputmsg(msg[0].num))
{
printf("%s\n",msg[0].data);
return;
}
printf("%s\n",msg[0].data);
printf("\n工号 姓名 性别 年龄 电话\n");
printf("\n %s\t %s\t %s\t %s\t %s\t\n",msg[0].num,msg[0].name,msg[0].sex,msg[0].age,msg[0].tel);
}
//按年龄查找
void Find_Age(int serverfd,Msg *msg)
{
int n = 0;
memset(msg,0,sizeof(Msg));
msg[0].type = FIND_AGE;
printf("提示:输入0返回更新员工信息菜单!\n");
printf("请输入年龄界限:");
scanf("%s",msg[0].age);
if (0 == inputmsg(msg[0].age))
{
return;
}
printf("请选择大于或小于此年龄:1-小于 2-大于 0-退出:");
scanf("%d",&n);
switch (n)
{
case 1:
strcpy(msg[0].data,"1");
break;
case 2:
strcpy(msg[0].data,"2");
break;
case 0:
return;
break;
default:
printf("输入错误!\n");
}
write(serverfd,msg,sizeof(Msg));
memset(msg,0,sizeof(Msg));
read(serverfd,msg,sizeof(Msg[MSG_MAX]));
if (0 == inputmsg(msg[0].num))
{
printf("%s\n",msg[0].data);
return;
}
else
{
printf("%s\n",msg[0].data);
printf("\n工号 姓名 性别 年龄 电话\n");
int i = 1;
for (;i <= msg[0].count;i++)
{
printf("\n %s\t %s\t %s\t %s\t %s\t\n",msg[i].num,msg[i].name,msg[i].sex,msg[i].age,msg[i].tel);
}
}
}
//按工号排序
void Sort_Num(int serverfd,Msg *msg,int Istravel)
{
memset(msg,0,sizeof(Msg));
msg[0].type = SORT_NUM;
write(serverfd,msg,sizeof(Msg));
memset(msg,0,sizeof(Msg));
read(serverfd,msg,sizeof(Msg));
if (0 == inputmsg(msg[0].num))
{
printf("%s\n",msg[0].data);
return;
}
else
{
if (Istravel)
{
Travel_Info(serverfd,msg);
}
}
}
//按年龄排序
void Sort_Age(int serverfd,Msg *msg)
{
memset(msg,0,sizeof(Msg));
msg[0].type = SORT_AGE;
write(serverfd,msg,sizeof(Msg));
memset(msg,0,sizeof(Msg));
read(serverfd,msg,sizeof(Msg));
if (0 == inputmsg(msg[0].num))
{
printf("%s\n",msg[0].data);
return;
}
else
{
Travel_Info(serverfd,msg);
}
}
//遍历员工信息
void Travel_Info(int serverfd,Msg *msg)
{
memset(msg,0,sizeof(Msg[MSG_MAX]));
msg[0].type = TRAVEL;
write(serverfd,msg,sizeof(Msg));
//memset(msg,0,sizeof(Msg[MSG_MAX]));
read(serverfd,msg,sizeof(Msg[MSG_MAX]));
if (0 == inputmsg(msg[0].num))
{
printf("%s\n",msg[0].data);
return;
}
else
{
printf("%s\n",msg[0].data);
printf("\n工号 姓名 性别 年龄 电话\n");
int i = 0;
for (;i <= msg[0].count;i++)
{
printf("\n %s\t %s\t %s\t %s\t %s\t\n",msg[i].num,msg[i].name,msg[i].sex,msg[i].age,msg[i].tel);
}
}
}
//清空员工信息
void Destroy_Info(int serverfd,Msg *msg)
{
memset(msg,0,sizeof(Msg));
msg[0].type = DESTROY;
write(serverfd,msg,sizeof(Msg));
//memset(msg,0,sizeof(Msg));
read(serverfd,msg,sizeof(Msg[MSG_MAX]));
printf("%s\n",msg[0].data);
}
8、Makefile
同样加入了GDB调试参数。
OBJ = Socket.o Client.o Request.o help.o
client:$(OBJ)
gcc -g -o client $(OBJ) -lpthread
Client.o:Client.c Request.h
gcc -c Client.c
Socket.o:Socket.c Socket.h
gcc -c Socket.c
Request.o:Request.c Request.h
gcc -c Request.c
help.o:help.c help.h
gcc -c help.c
.PHONY:clean
clean:
rm client $(OBJ)
四、总结
以上就是员工管理系统的全部代码,有很多地方写的不好,但是作为学习的阶段性成果,还是很有纪念意义的。