C/C++实现FTP客户端,实现上传、下载、删除功能

#include <iostream>
#include "Winsock.h"
#include "windows.h"
#include "stdio.h"
#include <iostream>
#include <cstddef>
#pragma comment(lib, "wsock32.lib")	
using namespace std;

char ip[20]="";
char sendbuf[128] = "";
char recvbuf[128] = "";
void cmd_connect(SOCKET ConnectSocket,int port) {
	WSADATA wsaData;
	int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
	if (iResult != NO_ERROR)
		printf("Error at WSAStartup()\n");

	if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
		printf("WSAStartup 无法初始化!");
	}
	
	// 构建地址信息
	printf("请输入ip地址:");
	cin >> ip;
	sockaddr_in clientService;
	clientService.sin_family = AF_INET;
	clientService.sin_addr.s_addr = inet_addr(ip);	//指定IP
	clientService.sin_port = htons(port);
	if (connect(ConnectSocket, (SOCKADDR*)&clientService, sizeof(clientService)) == SOCKET_ERROR) {
		printf("连接失败\n");
		WSACleanup();
	}
	else {
		printf("连接成功\n");
		return ;
	}
}
SOCKET byte_connect(int port){
	WSADATA wsaData;
	int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
	if (iResult != NO_ERROR)
		printf("Error at WSAStartup()\n");

	if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
		printf("WSAStartup 无法初始化!");
	}
	SOCKET s = socket(AF_INET, SOCK_STREAM, 0);
	if (s == INVALID_SOCKET)
	{
		printf("socket error!");
	}
	sockaddr_in clientService;
	clientService.sin_family = AF_INET;
	clientService.sin_addr.S_un.S_addr = inet_addr(ip);	//指定IP
	clientService.sin_port = htons((unsigned short)port);
	if (connect(s, (SOCKADDR*)&clientService, sizeof(clientService)) == SOCKET_ERROR) {
		printf("%d\n", WSAGetLastError());
		printf("连接失败\n");
		WSACleanup();
	}
	else {
		printf("连接成功\n");
		return s;
	}
}
bool login(SOCKET ConnectSocket){
	char sendbuf[128] = "user ";
	char get[64] = "";
	char end[] = "\r\n";
	char recvbuf[128] = "";

	//用户名
	printf("请输入用户名:");
	cin >> get;
	strcat(sendbuf, get);
	strcat(sendbuf, end);
	memset(get, 0, sizeof(get));
	if (send(ConnectSocket, sendbuf, strlen(sendbuf), 0) > 0)
		printf("Bytes Sent: %s\n", sendbuf);
	memset(sendbuf, 0, sizeof(sendbuf));
	if (recv(ConnectSocket, recvbuf, 128, 0) > 0)
		printf("Bytes Recv: %s\n", recvbuf);
	memset(recvbuf, 0, sizeof(recvbuf));

	//密码
	char pwd[128] = "pass ";
	printf("请输入密码:");
	cin >> get;
	strcat(sendbuf, pwd);
	strcat(sendbuf, get);
	strcat(sendbuf, end);
	memset(get, 0, sizeof(get));
	if (send(ConnectSocket, sendbuf, strlen(sendbuf), 0) > 0)
		printf("Bytes Sent: %s\n", sendbuf);
	memset(sendbuf, 0, sizeof(sendbuf));

	//接收
	if (recv(ConnectSocket, recvbuf, 128, 0) > 0)
		printf("Bytes Recv: %s\n", recvbuf);
	
	char login_in[128] = "230 User logged in.\r\n";
	if (!strcmp(recvbuf, login_in))//0x010ff508 "230 User logged in.\r\n"
		return 1;
	else return 0;
}
SOCKET type(SOCKET ConnectSocket) {
	char type[20] = "TYPE I\r\n";
	strcpy_s(sendbuf, type);
	if (send(ConnectSocket, sendbuf, strlen(sendbuf), 0) > 0)
		printf("Bytes Sent: %s\n", sendbuf);
	memset(sendbuf, 0, sizeof(sendbuf));

	//接收
	if (recv(ConnectSocket, recvbuf, 128, 0) > 0)
		printf("Bytes Recv: %s\n", recvbuf);
	memset(recvbuf, 0, sizeof(recvbuf));
	return ConnectSocket;
}
SOCKET pasv(SOCKET ConnectSocket) {
	char pa[64] = "PASV\r\n";
	strcpy_s(sendbuf, pa);
	if (send(ConnectSocket, sendbuf, strlen(sendbuf), 0) > 0)
		printf("Bytes Sent: %s\n", sendbuf);
	memset(sendbuf, 0, sizeof(sendbuf));
	//接收
	if (recv(ConnectSocket, recvbuf, 128, 0) > 0)
		printf("Bytes Recv: %s\n", recvbuf);
	int po[6];
	char host[20];
	sscanf(recvbuf, "%*[^(](%d,%d,%d,%d,%d,%d)", &po[0], &po[1], &po[2], &po[3], &po[4], &po[5]);
	memset(recvbuf, 0, sizeof(recvbuf));
	sprintf(host, "%d.%d.%d.%d", po[0], po[1], po[2], po[3]);
	int port = 256 * po[4] + po[5];
	ConnectSocket = type(ConnectSocket);
	
	SOCKET ss = socket(AF_INET, SOCK_SEQPACKET, IPPROTO_TCP);
	ss = byte_connect(port);
	if (ss == INVALID_SOCKET)
	{
		printf("socket error!");
	}
	return ss;
}
void ls(SOCKET cmd_connect, SOCKET byte_connect) {
	memset(recvbuf, 0, sizeof(recvbuf));
	char ls[128] = "LIST\r\n";
	strcpy_s(sendbuf, ls);
	if (send(cmd_connect, sendbuf, strlen(sendbuf), 0) > 0)
		printf("Bytes Sent: %s\n", sendbuf);
	if (recv(cmd_connect, recvbuf, 128, 0) > 0)
		printf("Bytes Recv: %s\n", recvbuf);
	if (recv(byte_connect, recvbuf, 128, 0) > 0)
		printf("Bytes Recv: %s\n", recvbuf);
	memset(recvbuf, 0, sizeof(recvbuf));
	memset(sendbuf, 0, sizeof(sendbuf));
	return;
}
void download(SOCKET cmd_connect, SOCKET byte_connect) {
	FILE* op = NULL;
	op = fopen("te.txt", "wb");
	if (op == NULL) printf("dabukai");

	if (WSAGetLastError())
		printf("%d", WSAGetLastError());
	char retr[128] = "RETR te.txt\r\n";
	strcpy_s(sendbuf, retr);
	if (send(cmd_connect, sendbuf, strlen(sendbuf), 0) > 0)
		printf("Bytes Sent: %s\n", sendbuf);
		memset(sendbuf, 0, sizeof(recvbuf));
	

	size_t lens = 1, write_len = 0;
	while ((recv(byte_connect, recvbuf, 128, 0)) > 0)
	{
		if (recv(cmd_connect, recvbuf, 128, 0) > 0)
			printf("Bytes Recv: %s\n", recvbuf);
		memset(recvbuf, 0, sizeof(sendbuf));
		write_len = fwrite(&recvbuf, lens, 128, op);
		if (write_len != 128)//写入文件不完整
		{
			closesocket(byte_connect);//关闭套接字fclose(fp);//关闭文件
			printf("下载失败\n");
			return ;
		}		
	}
	printf("下载成功\n");
	fclose(op);
	return;
}
void upload(SOCKET cmd_connect, SOCKET byte_connect) {
	FILE* op = NULL;
	op = fopen("tp.txt", "rb");
	if (op == NULL) printf("dabukai");

	if (WSAGetLastError())
		printf("%d", WSAGetLastError());
	char retr[128] = "STOR tp.txt\r\n";//RETR  test.docx
	strcpy_s(sendbuf, retr);
	if (send(cmd_connect, sendbuf, strlen(sendbuf), 0) > 0)
		printf("Bytes Sent: %s\n", sendbuf);
	memset(sendbuf, 0, sizeof(sendbuf));

	size_t lens = 1, send_len = 0;
	if (recv(cmd_connect, recvbuf, 128, 0) > 0)
		printf("Bytes Recv: %s\n", recvbuf);
	while (lens > 0){
		lens = fread(sendbuf, 1, 128, op);
		send_len = send(byte_connect, sendbuf, lens, 0);
		memset(recvbuf, 0, sizeof(recvbuf));
		if (send_len != lens)
		{
			closesocket(byte_connect), fclose(op);
			printf("上传失败\n");
			return ;
		}
	}
	if (WSAGetLastError())
		printf("%d", WSAGetLastError());
	printf("上传成功\n");
	fclose(op);
	
	return;


}
void dele(SOCKET cmd_connect, SOCKET byte_connect) {
	memset(recvbuf, 0, sizeof(recvbuf));
	char de[128] = "DELE te.txt\r\n";
	strcpy_s(sendbuf, de);
	if (send(cmd_connect, sendbuf, strlen(sendbuf), 0) > 0)
		printf("Bytes Sent: %s\n", sendbuf);
	if (recv(cmd_connect, recvbuf, 128, 0) > 0)
		printf("Bytes Recv: %s\n", recvbuf);
	memset(recvbuf, 0, sizeof(recvbuf));
	memset(sendbuf, 0, sizeof(sendbuf));
	return;
}
void wait_op(SOCKET cmd_connect, SOCKET byte_connect) {
	char op[64]="";
	printf("操作:");
	cin >> op;
	if (!strcmp(op, "get"))
		download(cmd_connect, byte_connect);
	else if (!strcmp(op, "put"))
		upload(cmd_connect, byte_connect);
	else if (!strcmp(op, "ls"))
		ls(cmd_connect, byte_connect);
	else if (!strcmp(op, "de"))
		dele(cmd_connect, byte_connect);
	return;
}
DWORD startSocket() {	//开始连接
	 // 初始化Winsock
	WSADATA wsaData;
	int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
	if (iResult != NO_ERROR)
		printf("Error at WSAStartup()\n");
	if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) 
		printf("WSAStartup 无法初始化!");
	// 创建连接到服务器的SOCKET对象
	SOCKET ConnectSocket;
	ConnectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
	if (ConnectSocket == INVALID_SOCKET) {
		printf("Error at socket(): %ld\n", WSAGetLastError());
		WSACleanup();
		return 0;
	}
	cmd_connect(ConnectSocket, 21);
		// 声明和初始化变量
	if (recv(ConnectSocket, recvbuf, 128, 0) > 0)
		printf("Bytes Recv: %s\n", recvbuf);
	memset(recvbuf, 0, sizeof(recvbuf));

	bool login_or_not = FALSE;
	while (!login_or_not) {	//登录
		login_or_not = login(ConnectSocket);
	}

	SOCKET ss = socket(AF_INET, SOCK_SEQPACKET, IPPROTO_TCP);
	ss = pasv(ConnectSocket);
	if (ss == INVALID_SOCKET)
	{
		printf("socket error!");
	}
	//ss为数据链路
	///至此,指令链路与数据链路搭建完成,等待操作指令
	while (1){
		wait_op(ConnectSocket, ss);
	}
	// 释放资源
	WSACleanup();
	///
//}
}
int main() {
	startSocket();

}

上一篇:关于ftp的主动模式(Active Mode)和被动模式(Passive Mode)


下一篇:centos7安装vsftpd,配置