miniftp项目总结(三)

数据连接

  • 主动模式
    主动模式下连接的示意图:
    在这里插入图片描述
    客户端将自己的ip和port发送给服务器,等待服务器的主动连接。
    主动模式下,解析客户端发来的ip和port示意图:
    在这里插入图片描述
  • 被动模式
    被动模式的情况下,服务器建立TCP连接,客户端来连接服务器,服务器需要获取自己的ip和port,并发送给客户端。
  • 主动模式下工作的过程
    在这里插入图片描述
    leapftp 客户端显示的是图形界面,但是实际上服务器发送过来的是文本。所以我们只需要把目录的文本发送给客户端即可。
    在这里插入图片描述
    核心:怎么获取用户的目录
    结构体stat:
 struct stat {
               dev_t     st_dev;         /* ID of device containing file */
               ino_t     st_ino;         /* Inode number */
               mode_t    st_mode;        /* File type and mode */
               nlink_t   st_nlink;       /* Number of hard links */
               uid_t     st_uid;         /* User ID of owner */
               gid_t     st_gid;         /* Group ID of owner */
               dev_t     st_rdev;        /* Device ID (if special file) */
               off_t     st_size;        /* Total size, in bytes */
               blksize_t st_blksize;     /* Block size for filesystem I/O */
               blkcnt_t  st_blocks;      /* Number of 512B blocks allocated */

               /* Since Linux 2.6, the kernel supports nanosecond
                  precision for the following timestamp fields.
                  For the details before Linux 2.6, see NOTES. */

               struct timespec st_atim;  /* Time of last access */
               struct timespec st_mtim;  /* Time of last modification */
               struct timespec st_ctim;  /* Time of last status change */

           #define st_atime st_atim.tv_sec      /* Backward compatibility */
           #define st_mtime st_mtim.tv_sec
           #define st_ctime st_ctim.tv_sec
           };

结构体 dirent

        struct dirent {
               ino_t          d_ino;       /* Inode number */
               off_t          d_off;       /* Not an offset; see below */
               unsigned short d_reclen;    /* Length of this record */
               unsigned char  d_type;      /* Type of file; not supported
                                              by all filesystem types */
               char           d_name[256]; /* Null-terminated filename */
           };
const char* statbuf_get_perms(struct stat *sbuf)
{
	static char perms[] = "----------";
	perms[0] = '?';

	mode_t mode = sbuf->st_mode;
	switch (mode & S_IFMT) {
	case S_IFREG:
		perms[0] = '-';
		break;
	case S_IFDIR:
		perms[0] = 'd';
		break;
	case S_IFLNK:
		perms[0] = 'l';
		break;
	case S_IFIFO:
		perms[0] = 'p';
		break;
	case S_IFSOCK:
		perms[0] = 's';
		break;
	case S_IFCHR:
		perms[0] = 'c';
		break;
	case S_IFBLK:
		perms[0] = 'b';
		break;
	}

	if (mode & S_IRUSR) {
		perms[1] = 'r';
	}
	if (mode & S_IWUSR) {
		perms[2] = 'w';
	}
	if (mode & S_IXUSR) {
		perms[3] = 'x';
	}
	if (mode & S_IRGRP) {
		perms[4] = 'r';
	}
	if (mode & S_IWGRP) {
		perms[5] = 'w';
	}
	if (mode & S_IXGRP) {
		perms[6] = 'x';
	}
	if (mode & S_IROTH) {
		perms[7] = 'r';
	}
	if (mode & S_IWOTH) {
		perms[8] = 'w';
	}
	if (mode & S_IXOTH) {
		perms[9] = 'x';
	}
	if (mode & S_ISUID) {
		perms[3] = (perms[3] == 'x') ? 's' : 'S';
	}
	if (mode & S_ISGID) {
		perms[6] = (perms[6] == 'x') ? 's' : 'S';
	}
	if (mode & S_ISVTX) {
		perms[9] = (perms[9] == 'x') ? 't' : 'T';
	}

	return perms;
}

const char* statbuf_get_date(struct stat *sbuf)
{
	static char datebuf[64] = {0};
	const char *p_date_format = "%b %e %H:%M";//月 日 时 分
	struct timeval tv;//存储当前时间的结构体
	gettimeofday(&tv, NULL);//使用函数gettimeofday()函数来得到时间。它的精度可以达到微妙,第二个参数带回的是时区的信息,NULL默认是系统的时区
	time_t local_time = tv.tv_sec;
	if (sbuf->st_mtime > local_time || (local_time - sbuf->st_mtime) > 60*60*24*182)//早于系统时间半年前的时间格式
	{
		p_date_format = "%b %e  %Y";//月 日 年
	}
	//这一行做了修改!!!
	struct tm* p_tm = localtime(&sbuf->st_mtime);//根据文件创建总秒数得到标准时间
	strftime(datebuf, sizeof(datebuf), p_date_format, p_tm);

	return datebuf;
}
void list_common(session_t *sess)
{
	DIR *dir = opendir(".");
	if (dir == NULL)
	{
		return;
	}

	struct dirent *dt;
	struct stat sbuf;//stat结构体里面存的是读到的文件的信息
	while ((dt = readdir(dir)) != NULL)
	{
		if (lstat(dt->d_name, &sbuf) < 0)//获取链接文件的信息(不穿透)
		{
			continue;
		}
        if (dt->d_name[0] == '.') //判断隐藏文件的
		{
			continue;
        }

		char buf[1024] = {0};

		const char *perms = statbuf_get_perms(&sbuf);//sysutil中实现的

		int off = 0;
		//sprintf()函数的返回值:写入到 buffer 的字符数(不计空终止字符),或若输出错误或编码错误(对于字符串和字符转换指定符)发生则为负值。
		off += sprintf(buf, "%s ", perms);
		off += sprintf(buf + off, " %3d %-8d %-8d ", (int)sbuf.st_nlink, sbuf.st_uid, sbuf.st_gid);
		off += sprintf(buf + off, "%8lu ", (unsigned long)sbuf.st_size);

		const char *datebuf = statbuf_get_date(&sbuf);//sysutil中实现的
		off += sprintf(buf + off, "%s ", datebuf);
		if (S_ISLNK(sbuf.st_mode))//通过st_mode判断是不是链接文件
		{
			char tmp[1024] = {0};
			/*readlink()将符号链接路径名的内容放在
       		缓冲区buf,大小为bufsiz。  readlink()不附加null
       		字节到buf。它将(默默地)截断内容(达到一定长度)
       		的bufsiz字符),以防缓冲区太小而无法容纳所有
       		内容。成功执行后,这些调用将返回放置在buf中的字节数。
       		(如果返回的值等于bufsiz,则截断可能包含
       		错误发生时,返回-1并将errno设置为指示错误。
       		*/
			readlink(dt->d_name, tmp, sizeof(tmp));
			off += sprintf(buf + off, "%s -> %s\r\n", dt->d_name, tmp);
		}
		else
		{
			off += sprintf(buf + off, "%s\r\n", dt->d_name);
		}

		writen(sess->data_fd, buf, strlen(buf));
	}

	closedir(dir);
}

4 226 Directory send OK.

linux下时间函数的关系:
在这里插入图片描述获取用户目录中,文件时间的处理:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: FTP服务器,又称为File Transfer Protocol Server,是网络上的一种文件传输协议,主要用于将文件从一个网络地址传输到另一个网络地址。其中,FTP Server指的是运行FTP协议的服务器,它负责接受来自客户端的请求,并按照FTP协议的规定进行响应。 FTP服务器有着广泛的应用,其中最常见的是Web服务器中的FTP服务器。FTP服务器可以提供文件上传和下载服务,主要用于网站的文件发布、备份和存储等。此外,FTP服务器还可以用于文件的共享、远程控制、安装程序等多种应用场景。 在工作中,我们可能需要使用一些迷你FTP服务器,以方便我们进行一些文件的传输和共享。所谓迷你FTP服务器,指的是一些小型的FTP服务器软件,它们具有简单易用的操作界面和快速高效的文件传输速度,适用于小型团队和个人使用。 与传统的FTP服务器相比,迷你FTP服务器不仅功能强大,而且占用资源较少,使得它们得以在性能不足的电脑上运行。此外,迷你FTP服务器还可以方便地进行设置和配置,以满足用户的个性化需求。 总的来说,迷你FTP服务器是一种实用的工具,它为用户提供了一种快速、安全、高效的文件传输和共享方式,值得我们在工作和生活中多加利用。 ### 回答2: FTP服务器也就是File Transfer Protocol服务器,是一种可以实现文件传输的服务器,可以提供文件上传、下载和管理等功能。FTP服务器分为大型和迷你类两种,其中迷你FTP服务器由于其轻量、易用、便携等特性,成为了广泛应用的一种FTP服务器。 迷你FTP服务器具有简单易用的特点,可以轻松搭建FTP服务器并实现文件的上传和下载。其操作简单,用户只需创建FTP用户账号,指定其访问目录,就可以实现上传下载管理等功能。同时,迷你FTP服务器的便携性也是其具有优秀特性之一,它可以在不同计算机上使用,只需将软件安装在u盘或移动硬盘中,便携性大大提高了其使用的便利性。 迷你FTP服务器还具有可扩展性和高度可定制性。FTP服务器可以通过插件等方式来扩展其功能,并可以通过调整参数和配置来实现自定义的功能和使用方式。这样,用户就可以根据自己的需求进行定制化,提高FTP服务器的作用和效率。 总而言之,迷你FTP服务器是一种轻量级FTP服务器,具有简单易用、便携性、可扩展性和高度可定制性等优点。对于需要上传、下载和管理文件的小型组织或个人用户而言,迷你FTP服务器是一个不错的选择。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值