通过网络编程实现一个C/S模式的员工管理系统,服务器端用多进程或多线程模型支持多个客户端同时连接、操作。具体要求如下: (1)员工信息包括三个字段:姓名,年龄,手机号,用结构体表示; (2)服务器功能: 添加新员工——接受客户端发送来的新员工结构体数据,追加到数据文件emp.db中; 获取员工列表——把emp.db中的每个员工结构体数据读出发回客户端; (3)客户端功能: 添加新员工——从终端读取新员工信息并构造为结构体变量,发到服务器请求添加新员工; 显示员工列表——向服务器请求员工列表,接收后显示到终端。 (4)客户端和服务器之间的协议应事先设计,如服务器返回给客户端的各类报告信息、错误信息都应事先统一设计好编号,类似真正DBMS那样。
时间: 2023-05-25 12:02:42 浏览: 98
协议设计:
1. 添加新员工请求协议
| 字段 | 长度 | 描述 |
| --- | --- | --- |
| 请求类型 | 1 字节 | 固定值 1,表示添加新员工请求 |
| 姓名长度 | 1 字节 | 姓名字符串长度 |
| 姓名 | 可变 | 姓名字符串 |
| 年龄 | 4 字节 | 员工年龄 |
| 手机号长度 | 1 字节 | 手机号字符串长度 |
| 手机号 | 可变 | 手机号字符串 |
2. 添加新员工响应协议
| 字段 | 长度 | 描述 |
| --- | --- | --- |
| 响应类型 | 1 字节 | 固定值 11,表示添加新员工响应 |
| 结果 | 1 字节 | 0 表示成功,1 表示失败 |
| 错误描述长度 | 1 字节 | 错误描述字符串长度 |
| 错误描述 | 可变 | 错误描述字符串 |
3. 获取员工列表请求协议
| 字段 | 长度 | 描述 |
| --- | --- | --- |
| 请求类型 | 1 字节 | 固定值 2,表示获取员工列表请求 |
4. 获取员工列表响应协议
| 字段 | 长度 | 描述 |
| --- | --- | --- |
| 响应类型 | 1 字节 | 固定值 12,表示获取员工列表响应 |
| 员工数量 | 4 字节 | 员工数量 |
| 员工信息 | 可变 | 多个员工信息结构体 |
5. 员工信息结构体
| 字段 | 长度 | 描述 |
| --- | --- | --- |
| 姓名长度 | 1 字节 | 姓名字符串长度 |
| 姓名 | 可变 | 姓名字符串 |
| 年龄 | 4 字节 | 员工年龄 |
| 手机号长度 | 1 字节 | 手机号字符串长度 |
| 手机号 | 可变 | 手机号字符串 |
服务器端实现:
使用多进程模型实现,每当有一个客户端连接到服务器时,就开辟一个子进程来处理该客户端的请求。
服务器端程序伪代码如下:
1. 定义员工信息结构体
2. 定义添加员工和获取员工列表函数
```
int add_employee(employee_t emp)
{
// 打开 emp.db 文件,以追加方式写入 emp 结构体数据
// 写入成功返回 0,失败返回 -1
}
int get_employee_list(employee_t **emp_list, int *n_emp)
{
// 打开 emp.db 文件,读取员工信息结构体到 emp_list 中
// 读取成功返回 0,失败返回 -1,同时 emp_list 和 n_emp 的值置为 NULL 和 0
}
```
3. 定义处理客户端请求的函数
```
void handle_client(int sockfd)
{
// 接收客户端请求,根据请求类型调用相应的函数
// 发送响应结果到客户端,根据响应类型发送相应的数据
}
```
4. 主函数中创建监听套接字并建立连接。每当有新客户端连接到服务器,就开辟一个子进程来处理该客户端的请求。
```
int main()
{
// 创建监听套接字
// 绑定监听套接字并开始监听
// 循环等待客户端连接请求
// 接受连接请求并创建新的套接字
// 创建子进程来处理客户端请求
// 关闭新创建的套接字
// 等待子进程退出
// 关闭监听套接字
}
```
客户端实现:
客户端通过 TCP 协议连接服务器,发送相应的请求协议,接收服务器返回的响应结果。
客户端程序伪代码如下:
1. 建立连接
```
sockfd = socket(AF_INET, SOCK_STREAM, 0);
connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr));
```
2. 发送添加新员工请求
```
employee_t emp;
// 从终端读取新员工信息,构造为 emp 结构体
// 发送添加新员工请求协议到服务器
write(sockfd, add_employee_request_protocol_data, sizeof(add_employee_request_protocol_data));
```
3. 接收添加新员工响应
```
char buffer[MAX_PROTOCOL_DATA_SIZE];
// 接收服务器响应
read(sockfd, buffer, MAX_PROTOCOL_DATA_SIZE);
// 解析响应并处理
```
4. 发送获取员工列表请求
```
// 发送获取员工列表请求协议到服务器
write(sockfd, get_employee_list_request_protocol_data, sizeof(get_employee_list_request_protocol_data));
```
5. 接收获取员工列表响应
```
char buffer[MAX_PROTOCOL_DATA_SIZE];
// 接收服务器响应
read(sockfd, buffer, MAX_PROTOCOL_DATA_SIZE);
// 解析响应并处理
```
6. 关闭连接
```
close(sockfd);
```
阅读全文