Linux下 Socket服务器和客户端文件互传

目录

1.项目描述

2.函数准备

2.1 gets函数

2.2 popen函数、fread函数

 2.3 access 函数

 2.4 exit 函数

 2.5 strtok 函数

2.6 chdir函数

3.项目代码

3.1服务器代码

3.2客户端代码

4.问题总结


1.项目描述

基于Soket聊天服务器,实现服务器和客户端的文件传输。

Linux系统下建立Socket聊天服务器_趣知boy的博客-CSDN博客

ls   获取服务器文件列表   
pwd  获取服务器当前路径
cd   对服务器目录的操作  +dir
quit 退出连接  put 上传文件到服务器  +file_name
get 获取服务器数据    +file_namelcd 对客户端目录的操作 +dir
lls 列出客户端所有文件 dofile 创建文件  

项目结构

2.函数准备

2.1 gets函数

gets 从标准输入流(通常是键盘)读取一行字符串,并将其存储在指定的字符数组中。

其比较重要的一个功能是阻塞

   printf("请输入您的姓名:");gets(name);printf("您的姓名是:%s\n", name);

2.2 popen函数、fread函数

size_t fread(void *ptr, size_t size, size_t count, FILE *stream);

 该函数可以读取指定数量(count = 1)的元素,每个元素的大小为size个字节,从指定文件(stream)中读取到内存指针(ptr)所指的位置。 

 2.3 access 函数

用于判断文件或目录是否具有某种权限。

int access(const char *pathname, int mode);
F_OK:检查文件是否存在
R_OK:检查读权限是否存在
W_OK:检查写权限是否存在
X_OK:检查执行权限是否存在

返回值:

  • 如果路径名指定的文件或目录具有所需的权限,则返回0。

  • 如果权限不足,则返回-1,并且errno设置为适当的错误码

 2.4 exit 函数

exit函数是一个用于终止程序运行的函数。当调用exit函数时,程序将立即退出并返回到操作系统。

 2.5 strtok 函数

char *strtok(char *str, const char *delim);

 其中str是要进行分割的字符串,delim是作为分隔符的字符串。函数返回一个指向被分割出的子字符串的指针。

strtok函数陷阱:会改变指针指向的字符串,所以想保留原来str需要用strcpy复制出来处理。

token = strtok(str, ",");
while (token != NULL) {printf("%s\n", token);token = strtok(NULL, ",");
}return 0;

执行上述代码会输出以下结果:

Hello

World

This

is

Strtok

2.6 chdir函数

更改当前工作目录

int chdir(const char *path);

参 数:Path 目标目录,可以是绝对目录或相对目录。

返回值:成功返回0 ,失败返回-1

3.项目代码

3.1服务器代码

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <ctype.h>
#include <arpa/inet.h>
#include "config.h" 
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>struct Msg msg;
int ss_fd;void handler_cmd(char *cmd){int cmd_int,fd;char *p;FILE *file;char *cmd_pre=cmd;//handle the cmd to numberif(!strcmp(cmd_pre,"ls")) cmd_int=ls;if(!strcmp(cmd_pre,"pwd")) cmd_int=pwd;  if(!strcmp(cmd_pre,"quit")) cmd_int=quit;if(!strcmp(cmd,"lls"))      cmd_int=lls;if(strstr(cmd,"lcd")!=NULL) cmd_int=lcd;if(strstr(cmd_pre,"cd")!=NULL) cmd_int=cd;if(strstr(cmd_pre,"put")!=NULL) cmd_int=put;if(strstr(cmd_pre,"get")!=NULL) cmd_int=get;//handle cmd switch(cmd_int){case ls:case pwd:file=popen(cmd,"r");fread(msg.data,sizeof(msg.data),1,file);printf("%s",msg.data);write(ss_fd,&msg,sizeof(msg));break;case cd:p=strtok(cmd," ");p=strtok(NULL," ");printf("dir:%s \r\n",p);strcpy(msg.data,"change dir over \r\n");write(ss_fd,&msg,sizeof(msg));   //must give a msg backchdir(p);break;case get:p=strtok(cmd," ");p=strtok(NULL," ");printf("dir:%s \r\n",p);	if(!access(p,F_OK)){  //if have this filemsg.flag=dofile;fd=open(p,O_RDONLY);read(fd,&msg.data,sizeof(msg.data));send(ss_fd,&msg,sizeof(msg),0);close(fd);}else{   //if no this filesend(ss_fd,"no this file \r\n",16,0);}break;case put:p=strtok(cmd," ");p=strtok(NULL," ");printf("dir:%s \r\n",p);fd=open(p,O_RDWR|O_CREAT,0666);write(fd,&msg.data,strlen(msg.data));close(fd);strcpy(msg.data,"i have got a file.\r\n");write(ss_fd,&msg,sizeof(msg));   //must give a msg backbreak;case quit:msg.flag=quit;printf("quit==========\r\n");exit(-1);}}int main(void)
{int s_fd,nread,len;struct sockaddr_in s_ddr;  //build server msgstruct sockaddr_in c_ddr;  //save clinet msgs_fd= socket(AF_INET, SOCK_STREAM, 0);//1.build a soket specifiedif(s_fd==-1){perror("error is");}//2.build all binds_ddr.sin_family=AF_INET;s_ddr.sin_port=htons(8880);s_ddr.sin_addr.s_addr=htonl(INADDR_ANY);//give the bindbind(s_fd,(struct sockaddr *)&s_ddr,sizeof(s_ddr));//3.waite for clientlisten(s_fd,8);//4.accept come and connect for oncelen=sizeof(c_ddr);while(1){ss_fd=accept(s_fd,(struct sockaddr *)&c_ddr,&len);if(ss_fd == -1){perror("accept:");}printf("conect succese!==========\r\n");//5.read from connect ss_fdif(fork()==0){   //creat kid pid for handler msg and cmd //5.2 read	while(1){memset(&msg,'\0',sizeof(msg));   //clear msgprintf("====================\r\n");nread=read(ss_fd,&msg,sizeof(msg));if(nread==0){                 // cannot recv cmd printf("connect is cutdon! \r\n");break;}else{                        //can recive cmd printf("server  receved  cmd:%s \r\n",msg.cmd); printf("====================\r\n");handler_cmd(msg.cmd);    //hander the cmd  give msg data		}}}}close(ss_fd);close(s_fd);return 0;
}

3.2客户端代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include "config.h" 
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>int cmd_to_number(char *cmd)
{if(!strcmp(cmd,"ls")) return ls;if(!strcmp(cmd,"pwd")) return pwd;  if(!strcmp(cmd,"quit")) return quit;if(!strcmp(cmd,"lls")) return lls;if(strstr(cmd,"lcd")!=NULL) return lcd;if(strstr(cmd,"cd")!=NULL) return cd;if(strstr(cmd,"put")!=NULL) return put;if(strstr(cmd,"get")!=NULL) return get;return -1;}int handler_cmd(struct Msg msg, int s_fd)
{//handle cmd int fd,n_read; char p_pre[12];char *p=NULL;int ret=cmd_to_number(msg.cmd);switch(ret){case ls:case pwd:case cd:send(s_fd,&msg,sizeof(msg),0);break;case get:send(s_fd,&msg,sizeof(msg),0);break;case put:strcpy(p_pre,msg.cmd);printf("dir:%s \r\n",p_pre);p=strtok(p_pre," ");p=strtok(NULL," ");   //get file_name	printf("dir:%s \r\n",p);if(!access(p,F_OK)){  //if have this filefd=open(p,O_RDONLY);n_read=read(fd,&msg.data,1024);if(n_read>=1024){printf("file over 1024! faild! \r\n");} send(s_fd,&msg,sizeof(msg),0);memset(&msg.data,0,1024);printf("client put cmd is: %s \r\n",msg.cmd);close(fd);}else{   //if no this filesend(s_fd,"no this file",16,0);}break;			case lls:system("ls");break;case lcd:strcpy(p_pre,msg.cmd);p=strtok(p_pre," ");p=strtok(NULL," ");   //get file_printf("dir:%s \r\n",p);chdir(p);break;case quit:send(s_fd,&msg,sizeof(msg),0);close(s_fd); exit(-1);}return ret;
}  void handle_server_msg(struct Msg msg,int s_fd)
{int n_read,fd;char *p;struct Msg recv_msg; //this is new msg   use it becase need pre msg cmdn_read=read(s_fd,&recv_msg,sizeof(recv_msg));  //while blockif(n_read==0){printf("\r\n server is outline! ");exit(-1);}if(recv_msg.flag == dofile){p=strtok(msg.cmd," ");p=strtok(NULL," ");   //get file_name	fd=open(p,O_RDWR|O_CREAT,0666);printf("creat the file\r\n");write(fd,&recv_msg.data,strlen(recv_msg.data));close(fd);putchar('>');fflush(stdout);}else{           //normal direct cmdprintf("-------------------->\r\n");printf("%s >",recv_msg.data);printf("--------------------");putchar('>');fflush(stdout);}}int main(int argc,char *argv[])
{int flag,s_fd,n_read,ret;struct sockaddr_in c_ddr;struct Msg msg;//1.build sockets_fd=socket(AF_INET,SOCK_STREAM,0);//2.0 prepare server addrmemset(&c_ddr,0,sizeof(c_ddr)); //clear c_ddrc_ddr.sin_family=AF_INET;c_ddr.sin_port=htons(8880);inet_aton("127.0.0.1",&c_ddr.sin_addr);//2.connect server get s_fdif(connect(s_fd,(struct sockaddr *)&c_ddr,sizeof(c_ddr))==-1){perror("error");exit(-1);}printf("connect success==============\r\n");while(1){//1.get cmd form keyborad    and  handle cmd to servermemset(&msg,0,sizeof(msg));printf("\r\n >");gets(msg.cmd);int ret=handler_cmd(msg,s_fd);//2.handle the msg form serverif(ret==-1){printf("no this cmd!\r\n ");fflush(stdout);continue;}if(ret==5 || ret==6){printf("client cmd!\r\n ");fflush(stdout);continue;}	handle_server_msg(msg,s_fd);}close(s_fd);return 0;
} 

4.问题总结

  • 在put 发送文件中,当文件大小超过给定字节就会溢出,导致整个结构体崩坏,破坏cmd。
    思考:除了加大给定字节大小,还有其它办法吗?strcpy是怎么实现的
    read函数陷阱:read函数读的字节小于fd文件字节,会崩坏buf里的数据。
  • strtok函数会破坏使用的字符串,要保留原来字符串需要strcpy复制出来处理。
  • 本地命令不用服务器处理的命令,ret=5,ret=6不要进入hanle_server_msg用recv函数阻塞

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/68596.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Mendix如何实现导出文件

刚刚接触Mendix低代码两周&#xff0c;花了一周在b站看初级视频然后考完初级&#xff0c;第二周开始做个列表查询感觉照葫芦画瓢没啥难度。但最近要求写个导出列表数据&#xff0c;在mendix社区翻了翻&#xff0c;这个功能算是常见的。找了mendix官方提供的Docs磕磕盼盼才实现了…

双向交错CCM图腾柱无桥单相PFC学习仿真与实现(4)一些优化总结

前言 上一次说到单相的PFC硬件功能已经实现&#xff0c;THD3.15%满足了国标要求的范围&#xff0c;还是有优化的空间&#xff0c;目前系统设计的是6.6Kw&#xff0c;220V交流输出&#xff0c;400-800V直流输出。目前基本功能完成&#xff0c;但是还有很多细节需要优化&#xf…

科技驱动产业升级:浅谈制造型企业对MES系统的应用

在科技不断进步的背景下&#xff0c;制造型行业也在持续发展&#xff0c;但随之而来的挑战也不断增加。传统的管理方式已经无法满足企业的需求&#xff0c;因此许多制造型企业开始寻找新的管理模式。制造执行系统&#xff08;MES&#xff09;作为先进的制造信息技术之一&#x…

学会这几步,教你1分钟辨出B站优质UP主!

品牌想要投放某UP主&#xff0c;该如何判断UP主是否优质并且同品牌相匹配呢&#xff1f;运用这一套多维度的UP主评估方法 &#xff0c;帮助你高效判断&#xff0c;快来看看具体怎么操作吧&#xff01; 一、up主粉丝涨跌 有些广告主在判断UP主是否值得投放时&#xff0c;会陷入…

9.3.tensorRT高级(4)封装系列-自动驾驶案例项目self-driving-车道线检测

目录 前言1. 车道线检测总结 前言 杜老师推出的 tensorRT从零起步高性能部署 课程&#xff0c;之前有看过一遍&#xff0c;但是没有做笔记&#xff0c;很多东西也忘了。这次重新撸一遍&#xff0c;顺便记记笔记。 本次课程学习 tensorRT 高级-自动驾驶案例项目self-driving-车道…

工服穿戴检测联动门禁开关算法

工服穿戴检测联动门禁开关算法通过yolov8深度学习框架模型&#xff0c;工服穿戴检测联动门禁开关算法能够准确识别和检测作业人员是否按照规定进行工服着装&#xff0c;只有当人员合规着装时&#xff0c;算法会发送开关量信号给门禁设备&#xff0c;使门禁自动打开。YOLO的结构…

港陆证券:五日线破位怎么看?

在股票交易中&#xff0c;五日线是个重要的技术指标之一&#xff0c;它能够反映出最近的商场趋势。假如五日线破位&#xff0c;这意味着商场呈现了趋势反转&#xff0c;出资者需求注重趋势改动&#xff0c;并采取相应的出资战略。 首先&#xff0c;咱们来看看五日线破位的原因…

【算法与数据结构】654、LeetCode最大二叉树

文章目录 一、题目二、解法三、完整代码 所有的LeetCode题解索引&#xff0c;可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、解法 思路分析&#xff1a;【算法与数据结构】106、LeetCode从中序与后序遍历序列构造二叉树这两道题有些类似&#xff0c;相关代…

OLED透明屏原彩优势和特点解析:开创显示技术新时代

OLED透明屏 原彩作为一项领先的显示技术&#xff0c;正以其卓越的性能和创新的设计特点引起广泛关注。 本文将通过深入探讨OLED透明屏 原彩的优势和特点、应用领域、技术发展以及未来前景等方面内容&#xff0c;并结合具体数据、报告和行业动态&#xff0c;为读者提供专业可信…

解决DNS服务器未响应错误的方法

​当你将设备连接到家庭网络或具有互联网接入功能的Wi-Fi热点时,由于各种原因,互联网连接可能无法正常工作。本文中的说明适用于Windows 10、Windows 8和Windows 7。 无法连接到DNS服务器的原因 故障的一类与域名系统有关,域名系统是世界各地互联网提供商使用的分布式名称…

W5500-EVB-PICO进行MQTT连接订阅发布教程(十二)

前言 上一章我们用开发板通过SNTP协议获取网络协议&#xff0c;本章我们介绍一下开发板通过配置MQTT连接到服务器上&#xff0c;并且订阅和发布消息。 什么是MQTT&#xff1f; MQTT是一种轻量级的消息传输协议&#xff0c;旨在物联网&#xff08;IoT&#xff09;应用中实现设备…

仿`gRPC`功能实现像调用本地方法一样调用其他服务器方法

文章目录 仿gRPC功能实现像调用本地方法一样调用其他服务器方法 简介单体架构微服务架构RPCgPRC gRPC交互逻辑服务端逻辑客户端逻辑示例图 原生实现仿gRPC框架编写客户端方法编写服务端方法综合演示 仿 gRPC功能实现像调用本地方法一样调用其他服务器方法 简介 在介绍gRPC简介…

【OpenCV入门】第五部分——图像运算

文章结构 掩模图像的加法运算图像的位运算按位与运算按位或运算按位取反运算按位异或运算图像位运算的运用 合并图像加权和覆盖 掩模 当计算机处理图像时&#xff0c;有些内容需要处理&#xff0c;有些内容不需要处理。能够覆盖原始图像&#xff0c;仅暴露原始图像“感兴趣区域…

Myvatis关联关系映射与表对象之间的关系

目录 一、关联关系映射 1.1 一对一 1.2 一对多 1.3 多对多 二、处理关联关系的方式 2.1 嵌套查询 2.2 嵌套结果 三、一对一关联映射 3.1 建表 ​编辑 3.2 配置文件 3.3 代码生成 3.4 编写测试 四、一对多关联映射 五、多对多关联映射 六、小结 一、关联关系映射 …

一文学会K8s集群搭建

环境准备 节点数量&#xff1a;2台虚拟机 centos7硬件配置&#xff1a;master节点内存至少3G&#xff08;2G后面在master节点初始化集群时会报错&#xff0c;内存不够&#xff09;&#xff0c;node节点可以2G&#xff0c;CPU至少2个&#xff0c;硬盘至少30G网络要求&#xff1…

Ant-Design-Pro-V5: ProTable前端导出excel表格。

Prtable表格中根据搜索条件实现excel表格导出。 代码展示&#xff1a; index.jsx import React, { useRef, useState, Fragment, useEffect } from react; import { getLecturerList, lecturerExportExcel } from /services/train/personnel; import { getOrgList, getSelec…

Navicat Premium 16.2.7 for Mac

Navicat Premium 16是一款功能强大的跨平台数据库管理工具&#xff0c;支持多种数据库类型&#xff0c;如MySQL、MariaDB、Oracle、SQLite、PostgreSQL等等。它提供了丰富的数据库管理功能和工具&#xff0c;可以帮助开发人员和数据库管理员快速地创建、管理和维护数据库。 Nav…

stable diffusion实践操作-大模型介绍

本文专门开一节写大模型相关的内容&#xff0c;在看之前&#xff0c;可以同步关注&#xff1a; stable diffusion实践操作 模型下载网站 国内的是&#xff1a;https://www.liblibai.com 国外的是&#xff1a;https://civitai.com&#xff08;科学上网&#xff09; 一、发展历…

自动化驱动程序管理

在部署操作系统时&#xff0c;每次都从下载和分发所需的驱动程序中实现真正的独立性可能是一场艰苦的战斗。特别是具有硬件多样化的环境&#xff0c;并且需要支持新的硬件类型时。借助 OS Deployer&#xff0c;可以对所有端点使用一个映像&#xff0c;无论品牌和型号如何&#…

【用unity实现100个游戏之7】从零开始制作一个仿杀戮尖塔卡牌回合制游戏

文章目录 前言素材资源开始一、UI框架二、挂载脚本三、事件监听&#xff0c;用于绑定按钮事件四、声音管理器五、excel转txt文本六、游戏配置七、用户信息表八、战斗管理器九、 敌人管理器十、玩家血量、能量、防御值、卡牌数十一、敌人血量 行动显示逻辑十二、UI提示效果实现十…