[Linux环境编程] socket网络套接字实现ftp客户端(网络编程)

本文介绍了Linux环境中使用socket实现FTP客户端的基本概念、程序效果、实现原理,包括目录操作、文件上传下载、断点续传等功能。通过分析代码,探讨了断点续传的实现细节,并总结了在设计多线程下载时遇到的问题,以加深对socket网络编程的理解。
摘要由CSDN通过智能技术生成

参考资料:《TCP/IP网络编程》

一、基本概念

1、socket套接字
所谓套接字(Socket),就是对网络中不同主机上的应用进程之间进行双向通信的端点的抽象。一个套接字就是网络上进程通信的一端,提供了应用层进程利用网络协议交换数据的机制。从所处的地位来讲,套接字上联应用进程,下联网络协议栈,是应用程序通过网络协议进行通信的接口,是应用程序与网络协议根进行交互的接口。
2、FTP通信协议
FTP(File Transfer Protocol,文件传输协议) 是 TCP/IP 协议组中的协议之一。FTP协议包括两个组成部分,其一为FTP服务器,其二为FTP客户端。其中FTP服务器用来存储文件,用户可以使用FTP客户端通过FTP协议访问位于FTP服务器上的资源。在开发网站的时候,通常利用FTP协议把网页或程序传到Web服务器上。此外,由于FTP传输效率非常高,在网络上传输大的文件时,一般也采用该协议。
默认情况下FTP协议使用TCP端口中的 20和21这两个端口,其中20用于传输数据,21用于传输控制信息。但是,是否使用20作为传输数据的端口与FTP使用的传输模式有关,如果采用主动模式,那么数据传输端口就是20;如果采用被动模式,则具体最终使用哪个端口要服务器端和客户端协商决定。

二、程序实现效果

在这里插入图片描述
在这里插入图片描述
ftp命令和该客户端登陆过程比对,接下来展示包括目录操作、文件上传和下载、断点续传、多线程下载等功能

目录操作:

在这里插入图片描述

ls -l:
在这里插入图片描述

文件上传:
在这里插入图片描述
文件下载:
在这里插入图片描述
断点续传:
在这里插入图片描述

三、实现原理

在这里插入图片描述
FTP使用2个TCP端口,首先是建立一个命令端口(控制端口),然后再产生一个数据端口。客户端从一个任意的非特权端口N(N>1024)连接到FTP服务器的命令端口(即tcp 21端口)。紧接着客户端开始监听端口N+1,并发送FTP命令“port N+1”到FTP服务器。最后服务器会从它自己的数据端口(20)连接到客户端指定的数据端口(N+1),这样客户端就可以和ftp服务器建立数据传输通道了。

四、代码分析

 #include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include "ftp_client.h"

// 创建FTP客户端对象
FTPClient* ftp = NULL;

void sigint(int num)
{
   
	if(ftp->is_get)
	{
   
		printf("------------------------\n");
		close(ftp->cli_pasv);
		close(ftp->cli_sock);
		close(ftp->fd);
		set_mtime(ftp->file,ftp->mtime);
		printf("------------------------\n");
	}
	if(ftp->is_put)
	{
   
		close(ftp->cli_pasv);
		close(ftp->fd);
		mdtm_FTPClient(ftp);
		close(ftp->cli_sock);
	}
	exit(EXIT_SUCCESS);
}

int main(int argc,const char* argv[])
{
   
	signal(SIGINT,sigint);
	if(2 == argc)
	{
   
		ftp = create_FTPClient(argv[1],21);
	}
	else if(3 == argc)
	{
   
		short port = atoi(argv[2]);
		ftp = create_FTPClient(argv[1],port);
	}
	else
	{
   
		printf("use:ftp xxx.xxx.xxx.xxx [port]\n");
		return EXIT_SUCCESS;
	}

	// 输入用户名
	char user[20] = {
   };
	printf("Name:");
	get_str(user,sizeof(user));
	user_FTPClient(ftp,user);
	
	// 密码并登录
	char pass[20] = {
   };
	printf("Password:");
	get_passwd(pass,sizeof(pass),0);
	pass_FTPClient(ftp,pass);

	// 循环的输入命令、执行命令
	char cmd[256] = {
   };
	for(;;)
	{
   
		printf("ftp> ");
		get_str(cmd,sizeof(cmd));

		if(0 == strncmp("pwd",cmd,3))
		{
   
			pwd_FTPClient(ftp);
		}
		else if(0 == strncmp("cd ",cmd,3))
		{
   
			cd_FTPClient(ftp,cmd+3);
		}
		else if(0 == strncmp("mkdir ",cmd,6))
		{
   
			mkdir_FTPClient(ftp,cmd+6);
		}
		else if(0 == strncmp("ls",cmd,2))
		{
   
			ls_FTPClient(ftp);
		}
		else if(0 == strncmp("put ",cmd,4))
		{
   
			put_FTPClient(ftp,cmd+4);
		}
		else if(0 == strncmp("get ",cmd,4))
		{
   
			get_FTPClient(ftp,cmd+4);
		}
		else if(0 == strncmp("bye",cmd,3))
		{
   
			bye_FTPClient(ftp);
			destory_FTPClient(ftp);
			return EXIT_SUCCESS;
		}
		else if('!' == cmd[0])
		{
   
			system(cmd+1);
		}
		else
		{
   
			printf("指针未定义!!!\n");
		}
	}
}

main函数:
设置各个的功能的函数入口,同时注册一个信号函数用于异常退出

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <time.h>
#include <utime.h>
#include <getch.h>
#include <sys/types.h>
#i
  • 3
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值