最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++實現(xiàn)簡單FTP客戶端軟件開發(fā)

 更新時間:2022年08月02日 14:02:57   作者:kk?star  
這篇文章主要為大家詳細(xì)介紹了C++實現(xiàn)簡單FTP客戶端軟件開發(fā),文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下

本文實例為大家分享了C++實現(xiàn)簡單FTP客戶端軟件開發(fā)的具體實現(xiàn)代碼,供大家參考,具體內(nèi)容如下

題目

簡單FTP客戶端軟件開發(fā)(100分)網(wǎng)絡(luò)環(huán)境中的一項基本應(yīng)用就是將文件從一臺計算機(jī)中復(fù)制到另一臺可能相距很遠(yuǎn)的計算機(jī)中。而文件傳送協(xié)議FTP是因特網(wǎng)上使用得最廣泛的文件傳送協(xié)議。FTP使用客戶服務(wù)器方式。

設(shè)計要求:

1)以命令行形式運(yùn)行
2)該FTP客戶端程序具有以下基本功能:能完成FTP鏈接的打開和關(guān)閉操作;能執(zhí)行文件的上傳和下載;能完成目錄的創(chuàng)建、刪除等有關(guān)操作。
3)設(shè)計中加入新的功能:登錄,進(jìn)入上級或下級目錄
要求可以傳輸簡單的文本文件。

設(shè)計思路

1、分為兩個端口,指令交流端口,數(shù)據(jù)交換端口
2、指令端口連接后一直保持通信,直到獲得退出信號
3、數(shù)據(jù)交換端口在獲得相關(guān)指令后重新建立連接

使用方法

1、分別創(chuàng)建兩個C++項目
2、復(fù)制代碼進(jìn)入即可
3、若兩個都在本地,使用本地回環(huán)測試IP,127.0.0.1
4、登錄的部分在客戶端中被注釋掉了沒有開啟

Tips:

目前登錄以及help部分仍有兩個小bug,系由端口的命令斷開以及連接部分引起,交由讀者自己研究,若不想管可以不使用這兩個功能

服務(wù)端——>Server

#include "Winsock2.h"
#include "windows.h"
#include <iostream>
#include <string>
using namespace std;

#define RECV_PORT 3312?? ?//接收端口
#define SEND_PORT 4302?? ?//發(fā)送端口
#define DATA_PORT 3313 ?//數(shù)據(jù)發(fā)送端口
#pragma comment(lib, "wsock32.lib")

SOCKET sockClient, sockServer;
SOCKET dataClient, dataServer;

sockaddr_in dataAddr;
sockaddr_in severAddr;//服務(wù)器地址
sockaddr_in ClientAddr;//客戶端地址
sockaddr_in dataClientAddr;//數(shù)據(jù)地址

int addrLen;?? ??? ?//地址長度
char fileName[20];?? ?//文件名
char order[20];?? ??? ?//命令
char rbuff[1024];?? ?//接收緩沖區(qū)
char sbuff[1024];?? ?//發(fā)送緩沖區(qū)

char namePassword[1024] = "user 123456";?? ?//用戶名和密碼

//***************函數(shù)聲明***************

DWORD startSock();
DWORD createSocket();
int sendFileRecord(SOCKET datatcps, WIN32_FIND_DATA *pfd);
int sendFileList(SOCKET datatcps);
int sendFile(SOCKET datatcps, FILE* file);
DWORD connectProcess();

//***************函數(shù)聲明***************
DWORD startSock() {//初始化winsock
?? ?WSADATA WSAData;
?? ?if (WSAStartup(MAKEWORD(2, 2), &WSAData) != 0) {
?? ??? ?cout << "初始化失敗" << endl;
?? ??? ?return -1;
?? ?}
?? ?return 1;
}
DWORD createSocket() {
?? ?sockClient = socket(AF_INET, SOCK_STREAM, 0);
? ? dataClient = socket(AF_INET, SOCK_STREAM, 0);
?? ?if (sockClient == SOCKET_ERROR||dataClient == SOCKET_ERROR) {
?? ??? ?cout << "創(chuàng)建失敗" << endl;
?? ??? ?WSACleanup();
?? ??? ?return -1;
?? ?}
? ? dataAddr.sin_family = AF_INET;
?? ?severAddr.sin_family = AF_INET;
? ? dataAddr.sin_addr.s_addr = htonl(INADDR_ANY);//監(jiān)聽任意地址
? ? dataAddr.sin_port = htons(DATA_PORT);
?? ?severAddr.sin_addr.s_addr = htonl(INADDR_ANY);//監(jiān)聽任意地址
? ? //cout<<htonl(INADDR_ANY)<<endl;
?? ?severAddr.sin_port = htons(RECV_PORT);
?? ?if (bind(sockClient, (struct sockaddr FAR*)&severAddr, sizeof(severAddr)) == SOCKET_ERROR||bind(dataClient, (struct sockaddr FAR*)&dataAddr, sizeof(dataAddr)) == SOCKET_ERROR) {
? ? ? ? //bind函數(shù)用于將socket和地址結(jié)構(gòu)綁定==
?? ??? ?cout << "綁定失敗" << endl;
?? ??? ?return -1;
?? ?}
?? ?return 1;
}

DWORD mkdir(char fileName[]){
? ? char path[1000];
? ? GetCurrentDirectory(sizeof(path), path);//找到當(dāng)前進(jìn)程的當(dāng)前目錄

? ? strcat(path,"\\");
? ? strcat(path,fileName);
? ? cout<<path<<endl;
? ? bool flag = CreateDirectory(path,NULL);
? ? if (flag)
? ? ? ? cout<<"創(chuàng)建文件:"<<fileName<<"成功"<<endl;
? ? else
? ? ? ? cout<<"創(chuàng)建文件:"<<fileName<<"失敗"<<endl;

}

DWORD delFile(char fileName[]){
? ? char path[1000];
? ? GetCurrentDirectory(sizeof(path), path);//找到當(dāng)前進(jìn)程的當(dāng)前目錄

? ? strcat(path,"\\");
? ? strcat(path,fileName);
? ?// cout<<path<<endl;
? ? bool flag = RemoveDirectory(path);
? ? if (flag)
? ? ? ? cout<<"刪除文件:"<<fileName<<"成功"<<endl;
? ? else
? ? ? ? cout<<"刪除文件:"<<fileName<<"失敗"<<endl;
}
DWORD connectProcess() {
?? ?addrLen = sizeof(ClientAddr);//addrLen是對象地址的長度

?? ?if (listen(sockClient, 10) < 0|| listen(dataClient, 10)<0) {//讓套接字進(jìn)入被動監(jiān)聽狀態(tài),參數(shù)2為請求隊列的最大長度
?? ??? ?cout << "監(jiān)聽失敗" << endl;
?? ??? ?return -1;
?? ?}
?? ?cout << "服務(wù)器正在監(jiān)聽中…" << endl;
?? ?while (1) {
?? ??? ?//accept取出隊列頭部的連接請求
?? ??? ?//sockclient是處于監(jiān)聽的套接字
?? ??? ?//ClientAddr 是監(jiān)聽的對象地址

?? ??? ?sockServer = accept(sockClient, (struct sockaddr FAR*)&ClientAddr, &addrLen);
?? ??? ?while (1) {

?? ??? ??? ?memset(rbuff, 0, sizeof(rbuff));
?? ??? ??? ?memset(sbuff, 0, sizeof(sbuff));
?? ??? ??? ?if (recv(sockServer, rbuff, sizeof(rbuff), 0) <= 0) {
? ? ? ? ? ? ? ? continue;
?? ??? ??? ?}
?? ??? ??? ?cout << endl << "獲取并執(zhí)行的命令:" << rbuff << endl;
?? ??? ??? ?if (strncmp(rbuff, "get", 3) == 0) {//將文件發(fā)給客戶端
?? ??? ??? ??? ?strcpy(fileName, rbuff + 4);
?? ??? ??? ??? ?FILE* file;//定義一個文件訪問指針
?? ??? ??? ??? ?//處理下載文件請求
?? ??? ??? ??? ?file = fopen(fileName, "rb");//二進(jìn)制打開文件,只允許讀
?? ??? ??? ??? ?if (file) {
?? ??? ??? ??? ??? ?sprintf(sbuff, "get %s", fileName);
?? ??? ??? ??? ??? ?if (!send(sockServer, sbuff, sizeof(sbuff), 0)) {
? ? ? ? ? ? ? ? ? ? ? ? cout<<"發(fā)送失敗"<<endl;
?? ??? ??? ??? ??? ??? ?fclose(file);
?? ??? ??? ??? ??? ??? ?return 0;
?? ??? ??? ??? ??? ?}
?? ??? ??? ??? ??? ?else {//創(chuàng)建額外數(shù)據(jù)連接傳送數(shù)據(jù)
?? ??? ??? ??? ??? ??? ?if (!sendFile(dataClient, file)) {
?? ??? ??? ??? ??? ??? ??? ?return 0;
?? ??? ??? ??? ??? ??? ?}
?? ??? ??? ??? ??? ??? ?fclose(file);
?? ??? ??? ??? ??? ?}
?? ??? ??? ??? ?}else {
?? ??? ??? ??? ??? ?strcpy(sbuff, "無法打開文件\n");
? ? ? ? ? ? ? ? ? ? cout<<"無法打開文件"<<endl;
?? ??? ??? ??? ??? ?if (!send(sockServer, sbuff, sizeof(sbuff), 0)) {
?? ??? ??? ??? ??? ??? ?return 0;
?? ??? ??? ??? ??? ?}
?? ??? ??? ??? ?}
?? ??? ??? ?}//get
?? ??? ??? ?else if (strncmp(rbuff, "put", 3) == 0) {//從客戶端上傳上來文件

? ? ? ? ? ? ? ? cout<<"debug1"<<endl;
?? ??? ??? ??? ?FILE* fd;
?? ??? ??? ??? ?int cnt;
?? ??? ??? ??? ?strcpy(fileName, rbuff + 4);
?? ??? ??? ??? ?fd = fopen(fileName, "wb");

?? ??? ??? ??? ?if (fd == NULL) {
?? ??? ??? ??? ??? ?cout << "無法打開文件" << fileName << endl;
?? ??? ??? ??? ??? ?return 0;
?? ??? ??? ??? ?}
?? ??? ??? ??? ?sprintf(sbuff, "put %s", fileName);
?? ??? ??? ??? ?if (!send(sockServer, sbuff, sizeof(sbuff), 0)) {
?? ??? ??? ??? ??? ?fclose(fd);
?? ??? ??? ??? ??? ?return 0;
?? ??? ??? ??? ?}
?? ??? ??? ??? ?memset(sbuff, '\0', sizeof(rbuff));
? ? ? ? ? ? ? ? int dataAddLen = sizeof (dataClientAddr);
? ? ? ? ? ? ? ? dataServer = accept(dataClient, (struct sockaddr FAR*)&dataClientAddr, &dataAddLen);
?? ??? ??? ??? ?while ((cnt = recv(dataServer, rbuff, sizeof(rbuff), 0)) > 0) {
?? ??? ??? ??? ??? ?fwrite(rbuff, sizeof(char), cnt, fd);//把cnt個數(shù)據(jù)長度為char的數(shù)據(jù)從rbuff輸入到fd指向的文件
?? ??? ??? ??? ?}
?? ??? ??? ??? ?cout << "成功獲得文件" << fileName << endl;
? ? ? ? ? ? ? ? closesocket(dataServer);
?? ??? ??? ??? ?fclose(fd);
?? ??? ??? ?}//put
?? ??? ??? ?else if (strncmp(rbuff, "pwd", 3) == 0) {
?? ??? ??? ??? ?char path[1000];
?? ??? ??? ??? ?GetCurrentDirectory(sizeof(path), path);//找到當(dāng)前進(jìn)程的當(dāng)前目錄
?? ??? ??? ??? ?strcpy(sbuff, path);
?? ??? ??? ??? ?send(sockServer, sbuff, sizeof(sbuff), 0);
?? ??? ??? ?}//pwd
?? ??? ??? ?else if (strncmp(rbuff, "ls", 2) == 0) {
?? ??? ??? ??? ?strcpy(sbuff, rbuff);
?? ??? ??? ??? ?send(sockServer, sbuff, sizeof(sbuff), 0);
?? ??? ??? ??? ?sendFileList(dataClient);
?? ??? ??? ?}//dir
? ? ? ? ? ? else if(strncmp(rbuff, "mkdir", 5)==0){
? ? ? ? ? ? ? ? strcpy(fileName, rbuff + 6);
? ? ? ? ? ? ? ? strcpy(sbuff,rbuff);
? ? ? ? ? ? ? ? send(sockServer, sbuff, sizeof (sbuff),0);//發(fā)送回信息
? ? ? ? ? ? ? ? mkdir(fileName);
? ? ? ? ? ? }//mkdir
? ? ? ? ? ? else if(strncmp(rbuff,"del", 3)==0){
? ? ? ? ? ? ? ? strcpy(fileName, rbuff + 4);//獲得要刪的文件名
? ? ? ? ? ? ? ? strcpy(sbuff,rbuff);
? ? ? ? ? ? ? ? send(sockServer, sbuff, sizeof (sbuff),0);//發(fā)送回信息
? ? ? ? ? ? ? ? delFile(fileName);
? ? ? ? ? ? }//del
?? ??? ??? ?else if (strncmp(rbuff, "cd", 2) == 0) {
?? ??? ??? ??? ?strcpy(fileName, rbuff + 3);
?? ??? ??? ??? ?strcpy(sbuff, rbuff);
?? ??? ??? ??? ?send(sockServer, sbuff, sizeof(sbuff), 0);
? ? ? ? ? ? ? ? char path[1000];
? ? ? ? ? ? ? ? GetCurrentDirectory(sizeof(path), path);//找到當(dāng)前進(jìn)程的當(dāng)前目錄
? ? ? ? ? ? ? ? strcat(path,"\\");
? ? ? ? ? ? ? ? strcat(path,fileName);
?? ??? ??? ??? ?SetCurrentDirectory(path);//設(shè)置當(dāng)前目錄
?? ??? ??? ?}//cd
?? ??? ??? ?else if (strncmp(rbuff, "user", 4) == 0) {
?? ??? ??? ??? ?char tbuff[1024];
?? ??? ??? ??? ?strcpy(tbuff, rbuff + 5);
?? ??? ??? ??? ?strcat(tbuff, " ");
?? ??? ??? ??? ?memset(rbuff, '\0', sizeof(rbuff));
?? ??? ??? ??? ?strcpy(sbuff, "成功獲取用戶名\0");
?? ??? ??? ??? ?send(sockServer, sbuff, sizeof(sbuff), 0);

?? ??? ??? ??? ?recv(sockServer, rbuff, sizeof(rbuff), 0);
?? ??? ??? ??? ?cout << endl << "獲取并執(zhí)行的命令:" << rbuff << endl;
?? ??? ??? ??? ?strcat(tbuff, rbuff + 5);
?? ??? ??? ??? ?if (strcmp(tbuff, namePassword) == 0) {//驗證是否正確并返回數(shù)據(jù)給客戶端
?? ??? ??? ??? ??? ?send(sockServer, "right\0", sizeof(sbuff), 0);
?? ??? ??? ??? ?}else {
?? ??? ??? ??? ??? ?send(sockServer, "wrong\0", sizeof(sbuff), 0);
?? ??? ??? ??? ?}
?? ??? ??? ?}//user pass

?? ??? ?}
? ? ? ? closesocket(sockServer);
?? ?}
}
int sendFile(SOCKET datatcps, FILE* file) {
? ? int dataAddLen = sizeof (dataClientAddr);
? ? dataServer = accept(datatcps, (struct sockaddr FAR*)&dataClientAddr, &dataAddLen);
?? ?cout << "正在發(fā)送文件…" << endl;
?? ?memset(sbuff, '\0', sizeof(sbuff));
?? ?while(1) {//從文件中循環(huán)讀取數(shù)據(jù)并發(fā)送至客戶端
?? ??? ?int len = fread(sbuff, 1, sizeof(sbuff), file);//把file指針指向的文件中的內(nèi)容讀取到sbuff中
? ? ? ?//cout<<"sbuff內(nèi)容:"<<sbuff<<endl;
?? ??? ?if (send(dataServer, sbuff, len, 0) == SOCKET_ERROR) {
?? ??? ??? ?cout << "連接失敗" << endl;
?? ??? ??? ?closesocket(dataServer);
?? ??? ??? ?return 0;
?? ??? ?}
?? ??? ?if (len < sizeof(sbuff)) {//文件傳送結(jié)束
?? ??? ??? ?break;
?? ??? ?}
?? ?}
?? ?closesocket(dataServer);
?? ?cout << "發(fā)送成功" << endl;
?? ?return 1;
}
int sendFileList(SOCKET datatcps) {
? ? int dataAddLen = sizeof (dataClientAddr);
? ? dataServer = accept(datatcps, (struct sockaddr FAR*)&dataClientAddr, &dataAddLen);
?? ?HANDLE hff;?? ??? ??? ??? ??? ??? ??? ??? ?//建立一個線程
?? ?WIN32_FIND_DATA fd;?? ??? ??? ??? ??? ??? ?//搜索文件
?? ?hff = FindFirstFile("*", &fd);?? ??? ??? ?//查找文件來把待操作文件的相關(guān)屬性讀取到WIN32_FIND_DATA結(jié)構(gòu)中去
?? ?if (hff == INVALID_HANDLE_VALUE) {?? ??? ?//發(fā)生錯誤
?? ??? ?const char *errStr = "列出文件列表時發(fā)生錯誤\n";
?? ??? ?cout << *errStr << endl;
?? ??? ?if (send(dataServer, errStr, strlen(errStr), 0) == SOCKET_ERROR) {
?? ??? ??? ?cout << "發(fā)送失敗" << endl;
?? ??? ?}
?? ??? ?closesocket(dataServer);
?? ??? ?return 0;
?? ?}
?? ?BOOL flag = TRUE;
?? ?while (flag) {//發(fā)送文件信息

?? ??? ?if (!sendFileRecord(dataServer, &fd)) {
?? ??? ??? ?closesocket(dataServer);
?? ??? ??? ?return 0;
?? ??? ?}
?? ??? ?flag = FindNextFile(hff, &fd);//查找下一個文件
?? ?}
?? ?closesocket(dataServer);
?? ?return 1;
}
int sendFileRecord(SOCKET datatcps, WIN32_FIND_DATA *pfd) {//發(fā)送當(dāng)前的文件記錄
?? ?char fileRecord[MAX_PATH + 32];

?? ?FILETIME ft;?? ??? ??? ??? ??? ??? ?//文件的建立時間
?? ?FileTimeToLocalFileTime(&pfd -> ftLastWriteTime, &ft);//Converts a file time to a local file time.

?? ?SYSTEMTIME lastWriteTime;
?? ?FileTimeToSystemTime(&ft, &lastWriteTime);

?? ?const char *dir = pfd -> dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ? "<DIR>" : " ";
?? ?sprintf(fileRecord, "%04d-%02d-%02d %02d:%02d %5s %10d ? %-20s\n",
?? ??? ?lastWriteTime.wYear,
?? ??? ?lastWriteTime.wMonth,
?? ??? ?lastWriteTime.wDay,
?? ??? ?lastWriteTime.wHour,
?? ??? ?lastWriteTime.wMinute,
?? ??? ?dir,
?? ??? ?pfd -> nFileSizeLow,
?? ??? ?pfd -> cFileName
?? ?);
?? ?if (send(datatcps, fileRecord, strlen(fileRecord), 0) == SOCKET_ERROR) {
?? ??? ?//通過datatcps接口發(fā)送fileRecord數(shù)據(jù),成功返回發(fā)送的字節(jié)數(shù)
?? ??? ?cout << "發(fā)送失敗" << endl;
?? ??? ?return 0;
?? ?}
?? ?return 1;
}
int main(){

?? ?if (startSock() == -1 || createSocket() == -1 || connectProcess() == -1) {
?? ??? ?return -1;
?? ?}
?? ?return 1;
}

客戶端——>Client

#include <Winsock.h>
#include <windows.h>
#include <time.h>
#include <stdio.h>
#include <iostream>
using namespace std;

#define RECV_PORT 3312?? ?//接收端口
#define SEND_PORT 4302?? ?//發(fā)送端口
#define DATA_PORT 3313 ?//數(shù)據(jù)接受端口

#pragma comment(lib, "wsock32.lib")?? ?//加載ws2_32.dll,它是Windows Sockets應(yīng)用程序接口, 用于支持Internet和網(wǎng)絡(luò)應(yīng)用程序。

SOCKET sockClient;?? ??? ?//客戶端對象
sockaddr_in serverAddr;?? ?//服務(wù)器地址
sockaddr_in dataAddr;
SOCKET dataClient; ? ? ?//數(shù)據(jù)對象

char inputIP[20];?? ??? ?//存儲輸入的服務(wù)器IP
char fileName[20];?? ??? ?//文件名
char rbuff[1024];?? ??? ?//接收緩沖區(qū)
char sbuff[1024];?? ??? ?//發(fā)送緩沖區(qū)
bool checkFlag = false;?? ??? ??? ?//標(biāo)志是否通過登陸

//***********************函數(shù)聲明***********************
DWORD startSock();?? ??? ??? ??? ??? ??? ??? ?//啟動winsock并初始化
DWORD createSocket(SOCKET &mySocket);?? ??? ??? ??? ??? ??? ?//創(chuàng)建socket
DWORD callServer(SOCKET &mySocket,sockaddr_in addr);?? ??? ??? ??? ??? ??? ??? ?//發(fā)送連接請求

int command(); ? ? ? ? ? ? ? ? ? ? ? ? ? ? //執(zhí)行命令
void help();?? ??? ??? ??? ??? ??? ??? ??? ?//菜單
void list(SOCKET &sockfd);?? ??? ??? ??? ??? ?//列出遠(yuǎn)方當(dāng)前目錄
DWORD sendTCP(char data[]);?? ??? ??? ??? ??? ?//發(fā)送要執(zhí)行的命令至服務(wù)端
int user();?? ??? ??? ??? ??? ??? ??? ??? ??? ?//上傳用戶名
int pass();?? ??? ??? ??? ??? ??? ??? ??? ??? ?//上傳密碼
int sendFile(SOCKET &datatcps, FILE* file);?? ?//put 傳送給遠(yuǎn)方一個文件
//***********************函數(shù)聲明***********************


//***********************函數(shù)定義***********************
DWORD startSock() { //啟動winsock并初始化
? ? WSADATA WSAData;
? ? char a[20];
? ? memset(a, 0, sizeof(a));
? ? if (WSAStartup(MAKEWORD(2, 2), &WSAData) != 0) { //加載winsock版本
? ? ? ? cout << "sock初始化失敗" << endl;
? ? ? ? return -1;
? ? }
? ? if (strncmp(inputIP, a, sizeof(a)) == 0) {
? ? ? ? cout << "請輸入要連接的服務(wù)器IP:";
? ? ? ? cin >> inputIP;
? ? }
? ? //設(shè)置地址結(jié)構(gòu)
? ? serverAddr.sin_family = AF_INET;?? ??? ??? ??? ??? ?//表明底層是使用的哪種通信協(xié)議來遞交數(shù)據(jù)的,AF_INET表示使用 TCP/IPv4 地址族進(jìn)行通信
? ? serverAddr.sin_addr.s_addr = inet_addr(inputIP);?? ?//指定服務(wù)器IP,十進(jìn)制轉(zhuǎn)化成二進(jìn)制IPV4地址
? ? serverAddr.sin_port = htons(RECV_PORT);?? ??? ??? ??? ?//設(shè)置端口號,htons用于將主機(jī)字節(jié)序改為網(wǎng)絡(luò)字節(jié)序

? ? dataAddr.sin_family = AF_INET;
? ? dataAddr.sin_addr.s_addr = inet_addr(inputIP);
? ? dataAddr.sin_port = htons(DATA_PORT);//數(shù)據(jù)端口和控制端口不一樣

? ? return 1;
}
DWORD createSocket(SOCKET &mySocket) { //創(chuàng)建socket
? ? //要使用套接字,首先必須調(diào)用socket()函數(shù)創(chuàng)建一個套接字描述符,就如同操作文件時,首先得調(diào)用fopen()函數(shù)打開一個文件。
? ? mySocket = socket(AF_INET, SOCK_STREAM, 0);//當(dāng)scoket函數(shù)成功調(diào)用時返回一個新的SOCKET(Socket Descriptor) //SOCK_STREAM(流式套接字):Tcp連接,提供序列化的、可靠的、雙向連接的字節(jié)流。支持帶外數(shù)據(jù)傳輸
? ? if (mySocket == SOCKET_ERROR) {
? ? ? ? cout << "創(chuàng)建socket失敗" << endl;
? ? ? ? WSACleanup();//終止Ws2_32.dll 的使用
? ? ? ? return -1;
? ? }
? ? return 1;
}
DWORD callServer(SOCKET &mySocket,sockaddr_in addr) { //發(fā)送連接請求
? ? createSocket(mySocket);
? ? if (connect(mySocket, (struct sockaddr*)&addr, sizeof(addr)) == SOCKET_ERROR) {//connect()創(chuàng)建與指定外部端口的連接
? ? ? ? cout << "連接失敗" << endl;
? ? ? ? memset(inputIP, 0, sizeof(inputIP));
? ? ? ? return -1;
? ? }
? ? return 1;
}
void help() { //幫助菜單
? ? cout << " ? ? ? ?___________________________________________ ?" << endl
? ? ? ? ?<< " ? ? ? | ? ? ? ? ? ? ? ?FTP幫助菜單 ? ? ? ? ? ? ? ? | ? " << endl
? ? ? ? ?<< " ? ? ? | 1、get 下載文件 [輸入格式: get 文件名 ] ? ? ? | ? " << endl
? ? ? ? ?<< " ? ? ? | 2、put 上傳文件 [輸入格式:put 文件名] ? ? ? ? | ? " << endl
? ? ? ? ?<< " ? ? ? | 3、pwd 顯示當(dāng)前文件夾的絕對路徑 ? ? ? ? ? ? ? ?| ? ?" << endl
? ? ? ? ?<< " ? ? ? | 4、ls 顯示遠(yuǎn)方當(dāng)前目錄的文件 ? ? ? ? ? ? ? ? | ? " << endl
? ? ? ? ?<< " ? ? ? | 5、mkdir 新建文件夾 [輸入格式:mkdir 文件名] ? | ? " << endl
? ? ? ? ?<< " ? ? ? | 6、del 刪除文件夾 [輸入格式:del 文件名] ? ? ? | ? " << endl
? ? ? ? ?<< " ? ? ? | 7、cd ?改變遠(yuǎn)方當(dāng)前目錄和路徑 ? ? ? ? ? ? ? ? | ? " << endl
? ? ? ? ?<< " ? ? ? | ? ? ? ? 進(jìn)入下級目錄: cd 路徑名 ? ? ? ? ? ? ?| ? " << endl
? ? ? ? ?<< " ? ? ? | ? ? ? ? 進(jìn)入上級目錄: c .. ? ? ? ? ? ? ? ? ?| ? " << endl
? ? ? ? ?<< " ? ? ? | 8、? 或者 help 進(jìn)入幫助菜單 ? ? ? ? ? ? ? ? ?| ? " << endl
? ? ? ? ?<< " ? ? ? | 9、quit 退出FTP ? ? ? ? ? ? ? ? ? ? ? ? ? ?| ? " << endl
? ? ? ? ?<< " ? ? ? |___________________________________________| ? ?" << endl;
}
DWORD sendTCP(char data[]) { //發(fā)送要執(zhí)行的命令至服務(wù)端
? ? int length = send(sockClient, data, strlen(data), 0);
? ? if (length <= 0) {
? ? ? ? cout << "發(fā)送命令至服務(wù)端失敗" << endl;
? ? ? ? closesocket(sockClient);//當(dāng)不使用socket()創(chuàng)建的套接字時,應(yīng)該調(diào)用closesocket()函數(shù)將它關(guān)閉,就如同調(diào)用fclose()函數(shù)關(guān)閉一個文件,用來進(jìn)行套接字資源的釋放。
? ? ? ? WSACleanup();
? ? ? ? return -1;
? ? }
? ? return 1;
}
int sendFile(SOCKET &datatcps, FILE* file) { //put 傳送給遠(yuǎn)方一個文件
? ? callServer(datatcps,dataAddr);
? ? cout << "正在傳輸文件…" << endl;
? ? memset(sbuff, '\0', sizeof(sbuff));
? ? while (1) { //從文件中循環(huán)讀取數(shù)據(jù)并發(fā)送
? ? ? ? int len = fread(sbuff, 1, sizeof(sbuff), file); //fread從file文件讀取sizeof(sbuff)長度的數(shù)據(jù)到sbuff,返回成功讀取的數(shù)據(jù)個數(shù)

? ? ? ? if (send(datatcps, sbuff, sizeof(rbuff), 0) == SOCKET_ERROR) {
? ? ? ? ? ? cout << "與客戶端的連接中斷" << endl;
? ? ? ? ? ? closesocket(datatcps);
? ? ? ? ? ? return 0;
? ? ? ? }
? ? ? ? if (len < sizeof(sbuff)) {
? ? ? ? ? ? break;
? ? ? ? }
? ? }
? ? closesocket(datatcps);
? ? cout << "傳輸完成" << endl;
? ? return 1;
}
void list(SOCKET &sockfd) { //列出遠(yuǎn)方當(dāng)前目錄
? ? callServer(sockfd,dataAddr);
? ? int nRead;
? ? memset(sbuff, '\0', sizeof(sbuff));
? ? while (1) {
? ? ? ? nRead = recv(sockfd, rbuff, sizeof(rbuff), 0);
? ? ? ? //recv通過sockClient套接口接受數(shù)據(jù)存入rbuff緩沖區(qū),返回接收到的字節(jié)數(shù)
? ? ? ? if (nRead == SOCKET_ERROR) {
? ? ? ? ? ? cout << "讀取時發(fā)生錯誤" << endl;
? ? ? ? ? ? exit(1);
? ? ? ? }
? ? ? ? if (nRead == 0) { //數(shù)據(jù)讀取結(jié)束
? ? ? ? ? ? break;
? ? ? ? }
? ? ? ? cout<<"nRead長度"<<nRead<<endl;
? ? ? ? //顯示數(shù)據(jù)
? ? ? ? rbuff[nRead] = '\0';
? ? ? ? cout << rbuff << endl;
? ? }
? ? cout<<"讀取結(jié)束"<<endl;
? ? closesocket(sockfd);
}
int ?user() {
? ? char operation[10], name[20];?? ??? ?//操作與文件名
? ? char order[30] = "\0";?? ??? ??? ??? ?//輸入的命令
? ? char buff[80];?? ??? ??? ??? ??? ??? ?//用來存儲經(jīng)過字符串格式化的order
? ? cout << "請輸入用戶名指令(user 用戶名):";
? ? strcpy(operation,"user");
? ? cin >> name;
? ? strcat(order, operation), strcat(order, " "), strcat(order, name);
? ? sprintf(buff, order);
? ? sendTCP(buff);?? ??? ??? ??? ??? ??? ??? ??? ??? ?//發(fā)送指令
? ? recv(sockClient, rbuff, sizeof(rbuff), 0);?? ??? ?//接收信息
? ? cout << rbuff << endl;
? ? return 1;
}
int pass() {
? ? char operation[10], name[20];?? ??? ?//操作與文件名
? ? char order[30] = "\0";?? ??? ??? ??? ?//輸入的命令
? ? char buff[80];?? ??? ??? ??? ??? ??? ?//用來存儲經(jīng)過字符串格式化的order
? ? cout << "請輸入密碼指令(pass 密碼):" ;
? ? strcpy(operation,"pass");
? ? cin >> name;
? ? strcat(order, operation), strcat(order, " "), strcat(order, name);
? ? sprintf(buff, order);
? ? sendTCP(buff);?? ??? ??? ??? ??? ??? ??? ??? ??? ?//發(fā)送指令
? ? recv(sockClient, rbuff, sizeof(rbuff), 0);?? ??? ?//接收信息
? ? cout << rbuff << endl;
? ? if (strcmp(rbuff, "wrong") == 0) {
? ? ? ? return 0;
? ? }
? ? return 1;
}
//***********************函數(shù)定義***********************

int command(){
? ? char operation[10], name[20]; ? ? ? ?//操作與文件名
? ? char order[30] = "\0"; ? ? ? ? ? ? ? ?//輸入的命令
? ? char buff[80]; ? ? ? ? ? ? ? ? ? ? ? ?//用來存儲經(jīng)過字符串格式化的order
? ? FILE *fd1, *fd2; ? ? ? ? ? ? ? ? ? ?//File協(xié)議主要用于訪問本地計算機(jī)中的文件,fd指針指向要訪問的目標(biāo)文件
? ? int cnt;
? ? //發(fā)送連接請求成功,初始化數(shù)據(jù)
? ? memset(operation, 0, sizeof(operation));
? ? memset(name, 0, sizeof(name));
? ? memset(order, 0, sizeof(order));
? ? memset(buff, 0, sizeof(buff));
? ? memset(rbuff, 0, sizeof(rbuff));
? ? memset(sbuff, 0, sizeof(sbuff));
? ? ? ? cout << endl << "請輸入要執(zhí)行的指令: ";
? ? ? ? cin >> operation;
// ? ? ? ?cout<<"why:"<<operation<<endl;
? ? ? ? if (strncmp(operation, "get", 3) == 0 || strncmp(operation, "put", 3) == 0 ||
? ? ? ? ? ? strncmp(operation, "cd", 2) == 0 || strncmp(operation, "mkdir", 5) == 0 || strncmp(operation, "del", 3) ==0){ ///需要輸入文件名的功能
? ? ? ? ? ? cin >> name;
? ? ? ? } else if (strncmp(operation, "quit", 4) == 0) { ///退出功能
? ? ? ? ? ? cout << "感謝您的使用" << endl;
? ? ? ? ? ? return 1;
? ? ? ? } else if (strncmp(operation, "?", 1) == 0 || strncmp(operation, "help", 4) == 0) { ///幫助菜單功能
? ? ? ? ? ? help();
? ? ? ? }else if(strncmp(operation,"ls",2)==0|| strncmp(operation,"pwd",3)==0){

? ? ? ? }
? ? ? ? else{
? ? ? ? ? ? cout<<"非法輸入"<<endl;
? ? ? ? ? ? return 0;
? ? ? ? }


? ? ? ? //將指令整合進(jìn)order,并存放進(jìn)buff
? ? ? ? strcat(order, operation), strcat(order, " "), strcat(order, name);

? ? ? ? sprintf(buff, order);
? ? ? ? sendTCP(buff); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//發(fā)送指令
? ? ? ? recv(sockClient, rbuff, sizeof(rbuff), 0); ? ? ? ?//接收信息
? ? ? ? cout << rbuff << endl; ? ? ? ? ? ? ? ? ? ? ? ? ? ?//pwd功能在這里已經(jīng)實現(xiàn)
? ? ? ? if (strncmp(rbuff, "get", 3) == 0) { ? ? ? ? ? ?///下載功能
? ? ? ? ? ? callServer(dataClient,dataAddr);
? ? ? ? ? ? fd1 = fopen(name, "wb"); ? ? ? ? ? ? ? ? ? ?//用二進(jìn)制的方式打開文件,wb表示打開或新建一個二進(jìn)制文件(只允許寫數(shù)據(jù))
? ? ? ? ? ? if (fd1 == NULL) {
? ? ? ? ? ? ? ? cout << "打開或者新建 " << name << "文件失敗" << endl;
? ? ? ? ? ? ? ? return 1;
? ? ? ? ? ? }
? ? ? ? ? ? memset(rbuff, '\0', sizeof(rbuff));
? ? ? ? ? ? while ((cnt = recv(dataClient, rbuff, sizeof(rbuff), 0)) > 0) {
? ? ? ? ? ? ? ?// cout<<"緩沖區(qū)"<<rbuff<<endl<<"長度"<<cnt<<endl;
? ? ? ? ? ? ? ? fwrite(rbuff, sizeof(rbuff), 1, fd1); ? ?//C 庫函數(shù) size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) 把 ptr 所指向的數(shù)組中的數(shù)據(jù)寫入到給定流 stream 中。
? ? ? ? ? ? }
? ? ? ? ? ? closesocket(dataClient);
? ? ? ? ? ? fclose(fd1); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//關(guān)閉文件
? ? ? ? }//get
? ? ? ? else if (strncmp(rbuff, "put", 3) == 0) { ///上傳功能
? ? ? ? ? // ?cout<<"執(zhí)行"<<endl;
? ? ? ? ? ? strcpy(fileName, rbuff + 4);
? ? ? ? ? ? fd2 = fopen(fileName, "rb"); ? ? ? ? ? ? ? ?//打開一個二進(jìn)制文件,文件必須存在,只允許讀
? ? ? ? ? ? if (fd2) { //成功打開
? ? ? ? ? ? ? ?// cout<<"debug0"<<endl;
? ? ? ? ? ? ? ? if (!sendFile(dataClient, fd2)) {
? ? ? ? ? ? ? ? ? ? cout << "發(fā)送失敗" << endl;
? ? ? ? ? ? ? ? ? ? return 1;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? fclose(fd2);
? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? strcpy(sbuff, "無法打開文件\n");
? ? ? ? ? ? ? ? if (!send(sockClient, sbuff, sizeof(sbuff), 0)) {
? ? ? ? ? ? ? ? ? ? return 1;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }

? ? ? ? }//put
? ? ? ? else if (strncmp(rbuff, "ls", 2) == 0) { ///ls功能
? ? ? ? ? ? list(dataClient);
? ? ? ? }//dir

? ? ? ? return 0;

}

int main() {
? ? while (1) {
? ? ? ? startSock(); ? ? ? ? ? ? ? ?//啟動winsock并初始化
? ? ? ? if (callServer(sockClient,serverAddr) == -1) { ? ?//發(fā)送連接請求失敗
? ? ? ? ? ? continue;
? ? ? ? }
? ? ? ? cout << "發(fā)送連接請求成功" << endl;

// ? ? ? ?if (checkFlag == false) {//登陸
// ? ? ? ? ? ?if (user() && pass()) {
// ? ? ? ? ? ? ? ?checkFlag = true;
// ? ? ? ? ? ?}
// ? ? ? ? ? ?continue;
// ? ? ? ?}
? ? ? ? checkFlag = true;

? ? ? ? if(checkFlag){
? ? ? ? ? ? help();
? ? ? ? }
? ? ? ? while(checkFlag){
? ? ? ? ? ? if(command()){
? ? ? ? ? ? ? ? break;
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? cout<<"命令輸入結(jié)束"<<endl;
? ? ? ? closesocket(sockClient); ? ?//關(guān)閉連接
? ? ? ? WSACleanup(); ? ? ? ? ? ? ? ?//釋放Winsock

? ? ? ? return 0;

? ? }
}
/*
192.168.0.100
user gyc
pass 123456
pwd
cd Debug
get 110.txt
*/

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • C++11 移動構(gòu)造函數(shù)的使用

    C++11 移動構(gòu)造函數(shù)的使用

    本文主要介紹了C++11 移動構(gòu)造函數(shù)的使用,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • C++ 內(nèi)聯(lián)函數(shù)inline案例詳解

    C++ 內(nèi)聯(lián)函數(shù)inline案例詳解

    這篇文章主要介紹了C++ 內(nèi)聯(lián)函數(shù)inline案例詳解,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-09-09
  • C++另辟蹊徑計算1到n的和

    C++另辟蹊徑計算1到n的和

    從1加到100,高斯的故事,我們學(xué)過。今天,我們寫一個程序來試試。首先,用笨方法。一個數(shù)一個數(shù)的加,我們一般人就是這樣干的嗎。在計算機(jī)程序里面,怎么辦呢?1我們把求和的功能寫成一個可以針對不同的N運(yùn)用的,C++里面叫函數(shù)
    2023-02-02
  • C語言大廠面試技巧及strcpy()函數(shù)示例詳解

    C語言大廠面試技巧及strcpy()函數(shù)示例詳解

    這篇文章主要為大家介紹了C語言面試技巧,以strcpy()函數(shù)為示例進(jìn)行分析詳解,有需要沖刺大廠的朋友們可以借鑒參考下,希望能夠有所幫助
    2021-11-11
  • C++獲取數(shù)組大小和多維數(shù)組操作詳解

    C++獲取數(shù)組大小和多維數(shù)組操作詳解

    這篇文章主要介紹了C++獲取數(shù)組大小和多維數(shù)組的操作,文中通過代碼示例介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2024-04-04
  • C++?std::chrono庫使用示例(實現(xiàn)C++?獲取日期,時間戳,計時等功能)

    C++?std::chrono庫使用示例(實現(xiàn)C++?獲取日期,時間戳,計時等功能)

    std::chrono是C++標(biāo)準(zhǔn)庫中的一個組件,用于表示和處理時間,這篇文章主要介紹了C++?std::chrono庫使用指南(實現(xiàn)C++?獲取日期,時間戳,計時等功能),需要的朋友可以參考下
    2023-06-06
  • C語言字符串函數(shù),字符函數(shù),內(nèi)存函數(shù)使用及模擬實現(xiàn)

    C語言字符串函數(shù),字符函數(shù),內(nèi)存函數(shù)使用及模擬實現(xiàn)

    這篇文章主要介紹了C語言字符串函數(shù),字符函數(shù),內(nèi)存函數(shù)使用及模擬實現(xiàn),文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-09-09
  • C++實現(xiàn)讀寫ini配置文件的示例代碼

    C++實現(xiàn)讀寫ini配置文件的示例代碼

    配置文件的讀取是每個程序必備的功能,配置文件的格式多種多樣,例如:ini格式、json格式、xml格式等。其中屬ini格式最為簡單,且應(yīng)用廣泛。本文和大家分享了C++讀寫ini配置文件的方法,需要的可以參考一下
    2023-05-05
  • C++ 如何使用RapidJson 寫入文件

    C++ 如何使用RapidJson 寫入文件

    RapidJSON 是只有頭文件的 C++ 庫, 不需要編譯, 可以直接在項目中使用, 只需把 include/rapidjson 目錄復(fù)制至系統(tǒng)或項目的 include 目錄即可,下面給大家分享C++ 如何使用RapidJson 寫入文件,感興趣的朋友跟隨小編一起看看吧
    2024-04-04
  • 關(guān)于PCL出現(xiàn)"無法找到?pcl_commond.dll?文件程序無法執(zhí)行"的問題及解決方法

    關(guān)于PCL出現(xiàn)"無法找到?pcl_commond.dll?文件程序無法執(zhí)行"的問題及解決方法

    這篇文章主要介紹了PCL出現(xiàn)"無法找到?pcl_commond.dll?文件程序無法執(zhí)行"的問題,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-07-07

最新評論

巴中市| 玛沁县| 陇川县| 新泰市| 梧州市| 达拉特旗| 邛崃市| 巴中市| 囊谦县| 疏附县| 镇巴县| 都江堰市| 张家界市| 札达县| 滁州市| 会同县| 屏东市| 雷州市| 阿克陶县| 安丘市| 闽侯县| 齐齐哈尔市| 阿拉善右旗| 新蔡县| 章丘市| 时尚| 兴安盟| 昭苏县| 泾源县| 闻喜县| 明光市| 元朗区| 敦化市| 应城市| 松阳县| 昌江| 五峰| 建湖县| 广灵县| 三亚市| 个旧市|