当前位置: 首页 > news >正文

网络编程项目之FTP服务器

项目介绍

模拟FTP核心原理:客户端连接服务器后,向服务器发送一个文件。文件名可以通过参数指定,服务器端接收客户端传来的文件(文件名随意),如果文件不存在自动创建文件,如果文件存在,那么清空文件然后写入。

项目功能介绍:

均有服务器和客户端代码,基于TCP写的。

在同一路径下,将客户端可执行代码复制到其他的路径下,接下来在不同的路径下运行服务器和客户端。

相当于另外一台电脑在访问服务器。

客户端和服务器链接成功后出现以下提示:四个功能

***************list************** //列出服务器所在目录下的文件名(除目录不显示)

***********put filename********** //上传一个文件

***********get filename********** //从服务器所在路径下载文件

**************quit*************** //退出(可只退出客户端,服务器等待下一个客户端链接)

FTP客户端

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <sys/stat.h>
#include <string.h>
#include <fcntl.h>char buf[128] = {};
//客户端函数声明
void putfileC(char *buf, int sockfd); //客户端上传文件到服务器功能函数
void getfileC(char *buf, int sockfd); //客户端从服务器下载文件功能函数
void list(int sockfd);int main(int argc, char const *argv[])
{// 1.创建套接字int sockfd = socket(AF_INET, SOCK_STREAM, 0);if (sockfd < 0){perror("socket err:");return -1;}// 2.填充结构体(ipv4)struct sockaddr_in addr;addr.sin_family = AF_INET;                 // 协议族ipv4addr.sin_port = htons(atoi(argv[2]));      // 端口号(网络字节序)addr.sin_addr.s_addr = inet_addr(argv[1]); // ip地址(网络字节序)// 3.连接if (connect(sockfd, (struct sockaddr *)&addr, sizeof(addr)) < 0){perror("connect err");return -1;}//4.发送while (1){fgets(buf, sizeof(buf), stdin);if (buf[strlen(buf) - 1] == '\n'){buf[strlen(buf) - 1] = '\0';}if (strcmp(buf, "quit") == 0){break;}if (strcmp(buf, "list") == 0){send(sockfd, buf, sizeof(buf), 0);list(sockfd);}if (strncmp(buf, "put ", 4) == 0){send(sockfd, buf, sizeof(buf), 0);putfileC(buf, sockfd);printf("put ok\n");}if (strncmp(buf, "get ", 4) == 0){send(sockfd, buf, sizeof(buf), 0);getfileC(buf, sockfd);printf("get ok\n");}}//5.关闭文件close(sockfd);return 0;
}void list(int sockfd)
{while (1){recv(sockfd, buf, sizeof(buf), 0);if (strcmp(buf, "end") == 0){break;}elseprintf("%s ", buf);}printf("\n");return;
}void putfileC(char *buf, int sockfd)
{int fd = open(buf + 4, O_RDONLY);if (fd < 0){perror("fd client err");return;}ssize_t ret;while (1){ret = read(fd, buf, sizeof(buf));if (ret == 0){break;}send(sockfd, buf, sizeof(buf), 0);memset(buf, 0, 128);}send(sockfd, "end", sizeof(buf), 0);close(fd);return;
}void getfileC(char *buf, int sockfd)
{int fd = open(buf + 4, O_WRONLY | O_CREAT | O_TRUNC, 0666);if (fd < 0){perror("fd  err");return;}ssize_t ret;while (1){memset(buf, 0, 128);ret = read(sockfd, buf, sizeof(buf));if (strcmp(buf, "end") == 0){break;}write(fd, buf, strlen(buf));}close(fd);return;
}

FTP服务器

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <sys/stat.h>
#include <string.h>
#include <fcntl.h>char buf[128] = {};
//服务器函数声明
void menu();                            //显示目录
void list(int acceptfd);                //列出服务器当前路径的文件名
void putfileS(char *buf, int acceptfd); //服务器接受客户端上传文件功能函数
void getfileS(char *buf, int acceptfd); //服务器下载文件到客户端功能函数int main(int argc, char const *argv[])
{//避免少输,出现段错误if (argc != 2){printf("please input %s ip port\n", argv[0]);return -1;}// 1.创建套接字int sockfd = socket(AF_INET, SOCK_STREAM, 0);if (sockfd < 0){perror("socket err:");return -1;}// 2.填充结构体(ipv4)struct sockaddr_in addr, caddr;       //客户端连接的时候会自己填充信息,只需给它个空间addr.sin_family = AF_INET;            // 协议族ipv4addr.sin_port = htons(atoi(argv[1])); // 端口号(网络字节序)addr.sin_addr.s_addr = INADDR_ANY;    // ip地址(网络字节序)// addr.sin_addr.s_addr = inet_addr("0.0.0.0");// 3.绑定int ret = bind(sockfd, (struct sockaddr *)&addr, sizeof(addr));if (ret < 0){perror("bind err:");return -1;}// 4.监听if (listen(sockfd, 5) < 0){perror("listen err");return -1;}//5.循环等待连接socklen_t len = sizeof(caddr);while (1){//有客户端连接就显示目录// 5.等待连接int acceptfd = accept(sockfd, (struct sockaddr *)&caddr, &len);if (acceptfd < 0){perror("accpet err:");return -1;}printf("acceptfd = %d\n", acceptfd);printf("client: ip=%s port=%d\n", inet_ntoa(caddr.sin_addr), ntohs(caddr.sin_port));// 6.接收menu();while (1){ret = recv(acceptfd, buf, sizeof(buf), 0);if (ret == -1){perror("recv err:");return -1;}else if (ret == 0){printf("client exit\n");break;}else{if (strcmp(buf, "list") == 0){list(acceptfd);}if (strncmp(buf, "put ", 4) == 0){putfileS(buf, acceptfd);printf("put end\n");}if (strncmp(buf, "get ", 4) == 0){getfileS(buf, acceptfd);printf("get end\n");}}}// 7.关闭close(acceptfd);}close(sockfd);return 0;
}void menu() //显示目录
{printf("***************list**************\n");printf("***********put filename**********\n");printf("***********get filename**********\n");printf("**************quit***************\n");
}
//列出服务器所在目录下的文件名(除目录不显示)
void list(int acceptfd)
{DIR *dirp;struct dirent *d;dirp = opendir("./");if (NULL == dirp){perror("opendir err");return;}struct stat st;while ((d = readdir(dirp)) != NULL){if (stat(d->d_name, &st) < 0){perror("stat err");return;}if ((st.st_mode & S_IFMT) == S_IFREG){send(acceptfd, d->d_name, sizeof(d->d_name), 0);}}send(acceptfd, "end", sizeof(buf), 0);
}
//服务器接受客户端上传文件功能函数
void putfileS(char *buf, int acceptfd)
{int fd = open(buf + 4, O_WRONLY | O_CREAT | O_TRUNC, 0666);if (fd < 0){perror("fd server err");return;}ssize_t ret;while (1){memset(buf, 0, 128);ret = recv(acceptfd, buf, sizeof(buf), 0);if (strcmp(buf, "end") == 0){break;}write(fd, buf, strlen(buf));}close(fd);return;
}
//服务器下载文件到客户端功能函数
void getfileS(char *buf, int acceptfd)
{int fd = open(buf + 4, O_RDONLY);if (fd < 0){perror("fd  err");return;}ssize_t ret;while (1){ret = read(fd, buf, sizeof(buf));if (ret == 0){break;}send(acceptfd, buf, sizeof(buf), 0);memset(buf, 0, 128);}send(acceptfd, "end", sizeof(buf),0);close(fd);return;
}

问题 

函数参数时把数组名传进去了,导致计算数组长度时报错,原因就是数组名被当作函数参数时会被降级为指针。

编译器警告:sizeof on array function parameter “arr‘ will return size “用另一个值除指针的sizeof值”,sizeof(数组名)时会遇到的坑-CSDN博客

c++数组传递参数与返回_function cannot return function type-CSDN博客 

函数使用数组的报错_sizeof' on array function parameter 'a' will retur-CSDN博客

粘包问题: 上传或下载都出现过服务器或客户端卡主现象,原因就是粘包问题没有解决,导致判断结束的"end"包与数据包粘在一起,判断条件不能满足跳不出循环一直卡主。目前我能解决的就是加个sleep函数先让发送或者接收数据的一方睡眠个几秒,或者收和发长度一致。

相关文章:

网络编程项目之FTP服务器

项目介绍 模拟FTP核心原理&#xff1a;客户端连接服务器后&#xff0c;向服务器发送一个文件。文件名可以通过参数指定&#xff0c;服务器端接收客户端传来的文件&#xff08;文件名随意&#xff09;&#xff0c;如果文件不存在自动创建文件&#xff0c;如果文件存在&#xff0…...

SpringBoot02:第一个springboot程序

3、第一个springboot程序 3.1、准备工作 我们将学习如何快速的创建一个Spring Boot应用&#xff0c;并且实现一个简单的Http请求处理。通过这个例子对Spring Boot有一个初步的了解&#xff0c;并体验其结构简单、开发快速的特性。 我的环境准备&#xff1a; java version "…...

快速入门HTML

欢迎关注个人主页&#xff1a;逸狼 创造不易&#xff0c;可以点点赞吗 如有错误&#xff0c;欢迎指出~ 目录 第一个html文件 标签 h1~h6 p >段落标签 br > 换行标签 img >图片标签 a >超链接标签 表格标签 表单标签 表单控件 form表单 ⽆语义标签:div&span 综…...

RabbitMQ是一个开源的消息代理和队列服务器

RabbitMQ是一个开源的消息代理和队列服务器&#xff0c;它基于AMQP&#xff08;Advanced Message Queuing Protocol&#xff0c;高级消息队列协议&#xff09;协议实现&#xff0c;同时也支持其他消息协议如STOMP、MQTT等。作为一个可靠的消息传递服务&#xff0c;RabbitMQ在分…...

经典算法思想--并查集

前言 &#xff08;最近在学习Java&#xff0c;所有函数都是用Java语言来书写的&#xff09;前言部分是一些前提储备知识 在并查集&#xff08;Union-Find&#xff09;数据结构中&#xff0c;rank&#xff08;中文称为“秩”&#xff09;是用来表示树的高度或深度的一种辅助信息…...

挑战Java面试题复习第2天,百折不挠

挑战第 2 天 ArrayList和linkedList的区别HashMap和HashTable的区别Collection 与 Collections 的区别Java的四种引用泛型常用特点 ArrayList和linkedList的区别 底层数据结构&#xff1a; ArrayList&#xff1a;基于动态数组实现&#xff0c;支持快速随机访问。LinkedList&a…...

【vue之道】

vue之道 1. 一生二&#xff0c;二生万物思想2. 变化之律3. 变化之实在哪&#xff1f;4.而后学于形乃已&#xff01;4.1 展示之形变4.2 动之气谓之指令4.3 血之养分的载体&#xff0c;于vue之绑定载具4.4 vue之道&#xff08;万法规一篇&#xff09; 1. 一生二&#xff0c;二生万…...

基于麻雀优化算法SSA的CEEMDAN-BiLSTM-Attention的预测模型

往期精彩内容&#xff1a; 时序预测&#xff1a;LSTM、ARIMA、Holt-Winters、SARIMA模型的分析与比较 全是干货 | 数据集、学习资料、建模资源分享&#xff01; EMD、EEMD、FEEMD、CEEMD、CEEMDAN的区别、原理和Python实现&#xff08;一&#xff09;EMD-CSDN博客 EMD、EEM…...

Linux:指令再认识

文章目录 前言一、知识点1. Linux下一切皆文件&#xff0c;也就是说显示器也是一种文件2. 指令是什么&#xff1f;3. ll 与 ls -l4. 日志5. 管道6. 时间戳 二、基本指令1. man指令2. cp指令3. mv指令4. 查看文件1&#xff09;cat/tac指令——看小文件2&#xff09;more/less指令…...

PHP如何抛出和接收错误

在PHP中&#xff0c;抛出和接收错误通常涉及异常处理机制&#xff0c;以及错误和异常的处理函数。以下是如何在PHP中抛出和接收错误的详细指南&#xff1a; 抛出错误&#xff08;异常&#xff09; 在PHP中&#xff0c;你可以使用throw关键字来抛出一个异常。这通常在你检测到…...

计算机网络:网络层 —— IPv4 地址的应用规划

文章目录 IPv4地址的应用规划定长的子网掩码变长的子网掩码 IPv4地址的应用规划 IPv4地址的应用规划是指将给定的 IPv4地址块 (或分类网络)划分成若干个更小的地址块(或子网)&#xff0c;并将这些地址块(或子网)分配给互联网中的不同网络&#xff0c;进而可以给各网络中的主机…...

Mongodb命令大全

Mongodb命令大全 一、数据库相关命令二、集合相关命令三、文档(数据)相关命令1、_id 字段说明2、查询2.1、 查询操作符2.2、内嵌文档查询2.3、数组文档查询2.4、去重查询2.5、查询排序 sort2.6、分页查询2.7、指定列投影查询返回2.8、查询统计个数 count 3、聚合查询3.1、查询用…...

宇视设备视频平台EasyCVR视频融合平台果园/鱼塘/养殖场/菜园有电没网视频监控方案

在那些有电无网的偏远地区&#xff0c;如果园、鱼塘、养殖场或菜园&#xff0c;视频监控的实现面临着独特的挑战。宇视设备视频平台EasyCVR提供了一种创新的解决方案&#xff0c;通过结合太阳能供电和4G摄像头技术&#xff0c;有效地解决了这些场景下的监控需求。 在有电没网的…...

面试题:ABCD四个线程,A线程最后执行

我觉得是一个很高频的面试题&#xff0c;ABCD四个线程&#xff0c;A线程要等到BCD线程执行完再执行&#xff0c;怎么做 因为我刚复习完AQS&#xff0c;所以立马想到了CountDownLatch&#xff0c;但是看面试官反应他最想听到的应该是join方法&#xff0c;所以面试后就总结了几种…...

代码随想录算法训练营第46期Day43

leetcode.322零钱兑换 class Solution { public: //无限个硬币->完全背包int coinChange(vector<int>& coins, int amount) {vector<int> dp(10010,INT_MAX);//dp代表的在某个数值下最小的硬币数&#xff0c;要求是最小的硬币数&#xff0c;所以初始值要尽可…...

前端处理API接口故障:多接口自动切换的实现方案

因为在开发APP&#xff0c;一个接口如果不通&#xff08;被挂了&#xff09;又不能改了重新打包让用户再下载软件更新&#xff0c;所以避免这种情况&#xff0c;跟后端讨论多备用接口地址自动切换的方案&#xff0c;自动切换到备用的接口地址&#xff0c;并保证后续所有的请求都…...

多租户架构的全景分析(是什么?基本概念、实现策略、资源管理和隔离、数据安全与隔离、性能优化、扩展性与升级、案例研究)

文章目录 1. 多租户的基本概念2. 多租户的实现策略2.1 独立数据库模式2.2 共享数据库-独立Schema模式2.3 共享数据库-共享Schema模式 3. 资源管理和隔离4. 数据安全与隔离5. 性能优化6. 扩展性与升级7. 案例研究总结 多租户架构在云计算和SaaS应用中越来越流行&#xff0c;因为…...

Git使用问题汇总附带解决方法(持续更新)

Git使用问题汇总附带解决方法 一 git pull 代码时报错&#xff1a; Auto packing the repository in background for optimum performance. See “git help gc“ 一 git pull 代码时报错&#xff1a; Auto packing the repository in background for optimum performance. See …...

Spring Boot驱动的植物健康监测革命

1系统概述 1.1 研究背景 随着计算机技术的发展以及计算机网络的逐渐普及&#xff0c;互联网成为人们查找信息的重要场所&#xff0c;二十一世纪是信息的时代&#xff0c;所以信息的管理显得特别重要。因此&#xff0c;使用计算机来管理植物健康系统的相关信息成为必然。开发合适…...

element 中 el-dialog 在不同的文件中使用

在实际中工作&#xff0c;我们经常需要使用 el-dialog 来做一个弹框的功能。最常见的就是在父组件中点击一个按纽&#xff0c;然后弹出一个框。而这个框就是子组件。同时&#xff0c;父子组件是分布在不同的文件中。 <!--父组件--> <template> <div> <…...

QT中采用QCustomPlot 实现将buffer中的数据绘制成折线图,并且图形随着数据更新而更新

QT中采用QCustomPlot 实现将buffer中的数据绘制成折线图,并且图形随着数据更新而更新 为了在 Qt 中将缓冲区的数据动态绘制成折线图,并随着数据的更新而实时更新,可以使用 QCustomPlot 或 Qt 自带的绘图功能,比如 QGraphicsView,或者在更简单的情况下使用 QPainter 在 QW…...

1688API商品详情接口如何获取

获取 1688API商品详情接口主要有以下步骤&#xff1a; 一、注册开发者账号&#xff1a; 访问 1688 开放平台&#xff0c;进行开发者账号注册。这是获取 API 接口使用权限的第一步&#xff0c;注册信息要确保真实准确。 二、了解接口规范和政策&#xff1a; 在 1688 开放平台…...

pytorch + d2l环境配置

文章目录 前言一、安装软件二、配置具体环境 前言 一直想写一篇 pytorch d2l的深度学习环境配置。但一直都不是很顺利&#xff0c;配置过很多次&#xff0c;都会遇到一些各种依赖项的兼容性问题。但这个是没有办法的&#xff0c;各种开源包都在不断维护过程中&#xff0c;版本…...

Go使用exec.Command() 执行脚本时出现:file or directory not found

使用 Go 提供的 exec.Command() 执行脚本时出现了未找到脚本的 bug&#xff0c;三个排查思路 &#xff1a; exec.Command(execName, args…) 脚本名字不允许相对路径 exec.Command(execName, args…) execName 只能有脚本名&#xff0c;不允许出现参数 如果你是使用 Windows …...

细节性知识(宏定义解析与宏的外部引用)

目录 一、问&#xff1a;#define N 50 中的N可以用来做运算比较吗&#xff1f; 二、宏定义怎么外部引用&#xff1f; 例子 总结 一、问&#xff1a;#define N 50 中的N可以用来做运算比较吗&#xff1f; 解析&#xff1a;在C语言中&#xff0c;#define N 50 是一个预处理指…...

面试中的JVM:结合经典书籍的深度解读

写在前面 &#x1f525;我把后端Java面试题做了一个汇总&#xff0c;有兴趣大家可以看看&#xff01;这里&#x1f449; ⭐️在无数次的复习巩固中&#xff0c;我逐渐意识到一个问题&#xff1a;面对同样的面试题目&#xff0c;不同的资料来源往往给出了五花八门的解释&#…...

使用语音模块的开发智能家居产品(使用雷龙LSYT201B 语音模块)

在这篇博客中&#xff0c;我们将探讨如何使用 LSYT201B 语音模块 进行智能设备的语音交互开发。通过这个模块&#xff0c;我们可以实现智能设备的语音识别和控制功能&#xff0c;为用户带来更为便捷和现代的交互体验。 1. 语音模块介绍 LSYT201B 是一个基于“芯片算法”的语音…...

深入理解支持向量机:从基本原理到实际应用

第6章 支持向量机 在本章中&#xff0c;我们将深入探讨支持向量机&#xff08;SVM&#xff09;这一强大的分类算法。SVM在模式识别和机器学习领域广泛应用&#xff0c;尤其在处理高维数据时表现出色。我们将依次讨论间隔与支持向量、对偶问题、核函数、间隔与正则化、支持向量…...

每天一题:洛谷P2041分裂游戏

题目描述 有一个无限大的棋盘&#xff0c;棋盘左下角有一个大小为 n 的阶梯形区域&#xff0c;其中最左下角的那个格子里有一枚棋子。你每次可以把一枚棋子“分裂”成两枚棋子&#xff0c;分别放在原位置的上边一格和右边一格。&#xff08;但如果目标位置已有棋子&#xff0c…...

简单的 curl HTTP的POSTGET请求以及ip port连通性测试

简单的 curl HTTP的POST&GET请求以及ip port连通性测试 1. 需求 我们公司有一个演示项目&#xff0c;需要到客户那边进行项目部署&#xff0c;项目部署完成后我们需要进行项目后端接口的测试功能&#xff0c;但是由于客户那边么有条件安装类似于postman这种的测试工具&am…...

谷秋精品课程网站建设软件/百度怎么推广自己的信息

1.简述编译型与解释型语言的区别&#xff0c;且分别列出你知道的哪些语言属于编译型&#xff0c;哪些属于解释型。 答: 编译型语言&#xff1a; 使用专门的编译器&#xff0c;针对特定的平台&#xff0c;将高级语言源代码一次性的编译成可被该平台硬件执行的机器码&#xff0c;…...

高明专业网站建设哪家好/国外免费推广网站有哪些

Aptana中的智能提示&#xff08;Code Assist&#xff09;是大家比较感兴趣的部分&#xff0c;也是它强于其他工具的重要部分。这里我再介绍几点。 一&#xff0e;快捷键 1&#xff0e;在Aptana中&#xff0c;你可以在文档的任何位置用 Alt/ 激活智能提示。 当然你也可以把它…...

php调用网站导航怎么弄/百度app平台

随着低代码如火如荼的发展&#xff0c;很多人浏览到相关文章时&#xff0c;看到少开发少些代码&#xff0c;会觉得那这种软件的发展不是在抢程序员“饭碗”吗&#xff1f; 首先必须要回答这个问题。不会打翻程序员“饭碗”的。低代码它不是万能的&#xff0c;程序员才是万能的…...

p2p网贷网站建设方案/山东济南seo整站优化费用

CPA全国青少年编程能力等级测评值得参加。CPA全国青少年编程能力等级测评考试内容难度适中&#xff0c;且分级考试&#xff0c;适合不同阶段的青少年参加。同时&#xff0c;从《青少年编程能力等级》标准中可以看到&#xff0c;“图形化编程“标准将分为三级&#xff0c;依次考…...

个人网页设计欣赏网站/百度推广需要什么条件

2019独角兽企业重金招聘Python工程师标准>>> 0&#xff0c;自从接触了github后&#xff0c;我对语言、技术就看得很开了&#xff0c;不再拘泥于自己的技术能力&#xff0c;把发现、学习、积累优秀项目作为核心能力之一&#xff1b; 1、想学习下设计模式&#xff0c;…...

教学网站开发应用指导方案/厦门零基础学seo

不同点&#xff1a; 1、签名不同&#xff1b; Android中的应用程序如何获得系统权限&#xff1f; 在 android 的 API中有提供 SystemClock.setCurrentTimeMillis()函数来修改系统时间&#xff0c;可惜无论你怎么调用这个函数都是没用的&#xff0c;无论模拟器还是真机&#xf…...