当前位置:网站首页>客户端与服务器通信项目2
客户端与服务器通信项目2
2022-04-22 07:43:00 【黑子的ball】
4、模块划分
4.1、服务器模块及功能
1、读取文件列表:获取服务器文件列表机文件详细信息
2、读取服务器配置:读取服务器名称与最大可连接数量
3、修改服务器配置:获取客户端发送的信息,并写入配置文件
4、开始传输文件:向客户端发送文件
5、暂停传输文件:暂停向客户端发送文件
6、停止传输文件:停止向客户端发送文件
7、多线程:同时响应多个客户端的连接,并处理响应的请求
4.2、客户端模块及功能
1、获取文件列表:接收服务器发送的文件列表信息,并打印
2、读取服务器配置:接收服务器发送的配置信息,并打印
3、修改服务器配置:输入配置信息,并发送给服务器
4、开始传输文件:从服务器下载文件
5、暂停传输文件:暂停从服务器下载文件
6、停止传输文件:停止从服务器下载文件
7、多线程:监听标准输入流,在文件传输过程中读取指令
5、结构体定义
5.1、描述客户端发送指令的结构体
typedef enum
{
GET_FILE_LIST = 1, //获取服务器文件列表
GET_SER_CONFIG, //获取服务器配置
SET_SER_CONFIG, //设置服务器配置
FILE_TRANS_START, //开始文件传输
FILE_TRANS_PAUSE, //暂停文件传输
FILE_TRANS_STOP, //停止文件传输
}cmd_type;
5.2、客户端与服务器之间的通信协议结构体
typedef struct protocol
{
int length; //整个文件的长度
int cmd; //对应数值的含义
char name[NAME_LEN]; //只有当命令为0x02时,该字段才生效
}protocol;
5.3、描述服务器配置的结构体
typedef struct server_config
{
char name[NAME_LEN]; //服务器名称
int client_max; //可连接最大客户端数量
}server_config;
5.4、描述传输文件信息的结构体
typedef struct file_info
{
char name[NAME_LEN]; //传输文件名
int length; //传输文件大小
}file_info;
5.5、描述文件传输状态
typedef enum
{
FILE_STATE_START = 1, //开始传输
FILE_STATE_PAUSE, //暂停传输
FILE_STATE_STOP, //结束传输
}file_state;
6、获取服务器文件列表
6.1、静态库
在本项目中,将获取服务器文件列表的功能以静态库的形式进行封装。链接时,链接器将从文件中取得所需的代码,复制到生成的可执行文件中,与程序运行的似乎无关
使用静态链接库的特点是可执行文件中包含了库代码的完整拷贝,但当多次使用时就会出现多份冗杂拷贝
6.2、功能实现
通常,我们在Linux系统中,都是使用ls命令来获取当前目录文件列表。本项目中,需要实现客户端发送指令获取服务器目录的文件列表,即需要将命令ls的返回值存储在缓冲区,然后发送给客户端。
(1)opendir()输入并打开当前目录,返回存放目录信息的结构体。
(2)readdir()循环读取目录,依次返回指向目录子项的指针,每次返回一个,读取一个子项则目录指针后移一位,直到目录结尾或出错
(3)逐个读取目录子项的信息,存放在stat结构体中。
(4)按序将子项信息以一定的格式存入缓冲区中
(5)closedir()关闭当前目录
最后,服务器将存放文件列表信息的缓冲区发送给客户端,客户端收到进行打印
7、服务器配置
在本项目中,该功能分为两部分,一部分是获取服务器配置,一部分是修改服务器配置。主要通过对文件的读写进行操作。为了保证每次修改后的配置在重启后仍然生效,项目中将服务器配置信息,保存在服务器配置文件中,放在服务器目录下。
7.1、获取服务器配置
当客户端发送指令需要获取服务器配置时候,服务器接收指令并执行getconfig()函数,读取配置文件内容:
name = 132
client_max = 9
(1)使用fgets()函数读取一行字符串
(2)strstr()函数来定位“=”在字符串中的位置
(3)将“=”后面的内容以字符串或者数字的形式存放到结构体“server_config”中
最后服务器将“server_config”结构体中的内容发送给客户端,客户端接收到服务器的配置信息后,打印在终端
7.2、修改服务器配置
当客户端需要修改服务器配置,并发送待配置的信息时,服务器接收指令,并执行“setconfig”函数,使用sprintf()函数将接收到的配置信息格式化后存入到字符串中,并写入文件
注:在修改服务器配置前,需要验证待配置参数的有效性
(1)最大可连接客户端数量不能超过系统设定的值,本设计中不能超过10
(2)最大可连接客户端数不能小于当前已连接的客户端数
8、文件传输
8.1、文件传输开始
(1)客户端发送开始传输的命令和待传输的文件名给服务器。当上一次文件传输结束时,客户端会提示输入新的文件名。当上一次文件传输未完成时,默认传输上一次的文件。
(2)服务器接收到开始传输的命令和待传输的文件名。
(3)首先判断文件名是否有效,若本地无该文件,则文件名无效,清空文件信息结构体返回给客户端;若该文件存在,则计算待传输的文件大小返回给客户端。当重新传输新文件时,大小为完整的文件字节数。当继续传输原来的文件时,大小为上一次未传输的字节数。
(4)客户端与服务器相互确认后开始进行文件的收发。当接收新文件时,文件以附加的方式打开。当接收的为上一次未传输完的文件时,文件以只写方式打开。
(5)当数据发送、接收完成,则文件传输成功
8.2、文件传输暂停
当客户端与服务器之间传输文件时,客户端的主线程处于忙碌的状态。此时,子线程用于处理标准输入流。当接收到暂停命令时,文件状态file_state置为FILE_STATE_PAUSE。客户端保存文件信息,并发送暂停指令给服务器。服务器接收到指令后暂停文件传输
8.3、文件传输停止
当客户端与服务器之间传输文件时,客户端的主线程处于忙碌的状态。此时,子线程用于处理标准输入流。当接收到停止命令时,文件状态file_state置为FILE_STATE_STOP。客户端清空文件信息,并发送停止指令给服务器。服务器接收到指令后停止文件传输。
9、多线程
在本项目中,服务器开启多线程是为了响应不同客户端连接,每当有一个新的客户端建立连接,并且当前连接数小于最大可连接客户端数量,便开启一个线程,用于和客户端之间的交互。每个线程处理一个客户端与服务器之间的通信,互不干扰。当该客户端与服务器之间的连接中断,线程也就会关闭。客户端开启多线程是为了在文件传输过程中读取标准输入流,防止数据的频繁收发阻塞了指令的读取。
9.1、创建线程
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void*(start_rountine)(void*), void *arg);
1、thread:存放新线程的ID到该参数所指向的缓存区中
2、attr:线程的属性,默认为NULL
3、start_routine:指定新线程的处理函数,也就是新线程启动之后需要执行的代码,线程处理函数执行完毕之后,新线程终止
4、arg:用于给start_routine传递实参
创建多线程,将特定的函数指定为线程来运行
9.2、互斥量
互斥量本质上就是一把锁,在访问共享资源前对互斥量进行加锁,在访问完成后释放互斥量上的锁。对互斥量进行加锁后,任何其他试图再次对互斥量加锁的线程都会被阻塞,直到当前线程释放该互斥锁。(初始化、锁定互斥、解锁互斥、销毁互斥)
pthread_mutex_t fastmutex = PTHREAD_MUTEX_INITIALIZER; //初始化
int pthread_mutex_lock(pthread_mutex_t *mutex); //锁定互斥
int pthread_mutex_unlock(pthread_mutex_t *mutex); //解锁互斥
int pthread_mutex_destroy(pthread_mutex_t *mutex); //销毁互斥
9.3、SELECT读取标准输入
当客户端在进行文件传输时,主线程处于忙碌状态,这时子线程就采用了select()函数来实现非阻塞读取标准输入。
(1)使用结构体timeval设置超时时间
(2)FD_ZERO()清空待检查的文件描述符
(3)FD_SET()设置文件描述符关联标准输入
(4)select()在超时时间系统内系统不断监听套接口状态。此时用于接收文件传输暂停或终止命令。返回-1表示出错,返回0表示超时,返回正数表示发生状态变化的文件描述符的个数
版权声明
本文为[黑子的ball]所创,转载请带上原文链接,感谢
https://blog.csdn.net/shark_93/article/details/120846088
边栏推荐
- SCRM加速行业化,制造业也开始玩私域流量了
- EFCore全局查询筛选器
- 记录node中使用sequelize,自动生成表模型,链接操作数据库(以postgreSQL为例)
- Airtest installation and introduction
- qt designer 跳转,布局,样式
- Machine learning notes - Mathematics in principal component analysis
- QT designer, jump, layout, style
- VirtualBox虚拟机(甲骨文Oracle VM )
- 236. 二叉树的最近公共祖先(Medium)
- ViewPager 全面总结
猜你喜欢

The domestic cloud security market has exceeded 10 billion yuan. What is the future development trend?

手把手教你实现RecyclerView的下拉刷新和上拉加载更多

MySQL in-depth study (Trinity): the use of PowerDesigner

postgres+postgis+geoserver离线路径规划功能(记录)
SmartTabLayout 简介

oh-my-notepro

What do you know about the well-known public DNS servers in China

函数指针和指针函数

Click, walk and move of characters in 3D sandbox game

【论文阅读】【3d目标检测】Voxel Set Transformer: A Set-to-Set Approach to 3D Object Detection from Point Clouds
随机推荐
国内云安全市场突破百亿元,未来发展趋势如何?
The starting point of the final end of the 15th day of the sprint to the big factory
国内知名公共 DNS 服务器居然有你知道哪些
Click, walk and move of characters in 3D sandbox game
Experiment 4: Data Preprocessing
Detailed analysis of viewpager usage
7-34 delete duplicate characters (set usage) & 7-35 count the number of characters (unordered_map)
7-34 删除重复字符(set用法)&&7-35 统计字符出现次数(unordered_map)
AC380V降5V12V24V200MA,超高压非隔离芯片IC方案
shell脚本学习笔记——shell对文件的操作sed
Goweb Foundation
【无极低码】低代码平台开发日记,低代码平台之sql编程
SCRM加速行业化,制造业也开始玩私域流量了
Flutter GridView Demo
kubernetes—实战入门
Make the airtest ide into a script and make the script run
【大话云原生】微服务篇-五星级酒店的服务方式
On the modification of static database
MaterialApp
关闭电脑端口