<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
本文為大家分享了FTP綜合應用程式設計(C++),供大家參考,具體內容如下
1.學校實驗
借鑑了網上一位大佬的作品,然後自己改改拿來完成了算是還行的作品。
程式碼一共大概是900多行,可以直接貼上下來看看,其實還是很容易理解的。
執行的截圖附上:
使用者端:
伺服器端:
2.伺服器端程式碼
標頭檔案:(sizes.h)
#pragma once //伺服器偵聽控制連線請求的埠 #define CMD_PORT 5858 //客戶機偵聽資料連線請求的埠 #define DATA_PORT 5850 //命令報文引數快取的大小 #define CMD_PARAM_SIZE 256 //回覆報文訊息快取的大小 #define RSPNS_TEXT_SIZE 256 #define BACKLOG 10 #define DATA_BUFSIZE 4096 //命令型別 typedef enum { LS, PWD, CD, DOWN, UP, QUIT } CmdID; //命令報文,從使用者端發往伺服器 typedef struct _CmdPacket { CmdID cmdid; char param[CMD_PARAM_SIZE]; } CmdPacket; //回覆報文的型別 typedef enum { OK, ERR } RspnsID; //回覆報文,從伺服器發往使用者端 typedef struct _RspnsPacket { RspnsID rspnsid; char text[RSPNS_TEXT_SIZE]; } RspnsPacket;
原始檔:(伺服器端.cpp)
#include <WinSock2.h> #include "sizes.h" #include <iostream> #pragma comment(lib, "ws2_32.lib") //建立執行緒時傳遞的資料結構,內含控制連線通訊端和使用者端地址資訊: struct threadData { SOCKET tcps; sockaddr_in clientaddr; }; //全域性函數宣告: //FTP初始化,建立一個偵聽通訊端: int InitFTP(SOCKET *pListenSock); int InitDataSocket(SOCKET *pDatatcps, SOCKADDR_IN *pClientAddr); int ProcessCmd(SOCKET tcps, CmdPacket* pCmd, SOCKADDR_IN *pClientAddr); int SendRspns(SOCKET tcps, RspnsPacket* prspns); int RecvCmd(SOCKET tcps, char* pCmd); int SendFileList(SOCKET datatcps); int SendFileRecord(SOCKET datatcps, WIN32_FIND_DATA* pfd); int SendFile(SOCKET datatcps, FILE* file); int RecvFile(SOCKET datatcps, char* filename); int FileExists(const char *filename); //執行緒函數,引數包括相應控制連線的通訊端: DWORD WINAPI ThreadFunc(LPVOID lpParam) { SOCKET tcps; sockaddr_in clientaddr; tcps = ((struct threadData *)lpParam)->tcps; clientaddr = ((struct threadData *)lpParam)->clientaddr; printf("socket的編號是:%u.n", tcps); //傳送回復報文給使用者端,內含命令使用說明: printf("Serve client %s:%dn", inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port)); RspnsPacket rspns = { OK, "歡迎進入FTP綜合應用系統!n" "你可以使用的命令:n" "lst<展示當前目錄下的檔案(夾),無需引數>n" "pwdt<展示當前目錄的絕對路徑,無需引數>n" "cdt<切換到指定目錄,引數為路徑>n" "downt<下載檔案,引數為檔名>n" "upt<上傳檔案,引數為檔名>n" "quitt<退出系統,無需引數>n" }; SendRspns(tcps, &rspns); //迴圈獲取使用者端命令報文並進行處理 for (;;) { CmdPacket cmd; if (!RecvCmd(tcps, (char *)&cmd)) break; if (!ProcessCmd(tcps, &cmd, &clientaddr)) break; } //執行緒結束前關閉控制連線通訊端: closesocket(tcps); delete lpParam; return 0; } int main(int argc, char* argv[]) { SOCKET tcps_listen; //FTP伺服器控制連線偵聽通訊端 struct threadData *pThInfo; if (!InitFTP(&tcps_listen)) //FTP初始化 return 0; printf("FTP伺服器開始監聽,埠號為:%d。。。。。。n", CMD_PORT); //迴圈接受使用者端連線請求,並生成執行緒去處理: for (;;) { pThInfo = NULL; pThInfo = new threadData; if (pThInfo == NULL) { printf("為新執行緒申請空間失敗。n"); continue; } int len = sizeof(struct threadData); //等待接受使用者端控制連線請求 pThInfo->tcps = accept(tcps_listen, (SOCKADDR*)&pThInfo->clientaddr, &len); //建立一個執行緒來處理相應使用者端的請求: DWORD dwThreadId, dwThrdParam = 1; HANDLE hThread; hThread = CreateThread( NULL, //無需安全性的繼承 0, //預設執行緒棧大小 ThreadFunc, //執行緒入口函數 pThInfo, //執行緒入口函數的引數 0, //立即啟動執行緒 &dwThreadId); //返回執行緒的id值 //檢查返回值是否建立執行緒成功 if (hThread == NULL) { printf("建立執行緒失敗。n"); closesocket(pThInfo->tcps); delete pThInfo; } } return 0; } //FTP初始化,建立一個偵聽通訊端: int InitFTP(SOCKET *pListenSock) { //按照此步驟建立新的伺服器端通訊端,嗯,沒錯,前三個都是這個步驟 //startup->socket->bind->listen WORD wVersionRequested; WSADATA wsaData; int err; SOCKET tcps_listen; wVersionRequested = MAKEWORD(2, 2); err = WSAStartup(wVersionRequested, &wsaData); if (err != 0) { printf("Winsock初始化時發生錯誤!n"); return 0; } if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) { WSACleanup(); printf("無效Winsock版本!n"); return 0; } tcps_listen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (tcps_listen == INVALID_SOCKET) { WSACleanup(); printf("建立Socket失敗!n"); return 0; } SOCKADDR_IN tcpaddr; tcpaddr.sin_family = AF_INET; tcpaddr.sin_port = htons(CMD_PORT); tcpaddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY); err = bind(tcps_listen, (SOCKADDR*)&tcpaddr, sizeof(tcpaddr)); if (err != 0) { err = WSAGetLastError(); WSACleanup(); printf("Scoket繫結時發生錯誤!n"); return 0; } err = listen(tcps_listen, 3); if (err != 0) { WSACleanup(); printf("Scoket監聽時發生錯誤!n"); return 0; } *pListenSock = tcps_listen; return 1; } //建立資料連線 //pDatatcps:用於儲存資料連線通訊端 //pClientAddr:指向使用者端的控制連線通訊端地址,需要使用其中的IP地址 //返回值:0表示失敗,1正常 int InitDataSocket(SOCKET *pDatatcps, SOCKADDR_IN *pClientAddr) { SOCKET datatcps; //建立socket datatcps = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (datatcps == INVALID_SOCKET) { printf("Creating data socket failed!n"); return 0; } SOCKADDR_IN tcpaddr; memcpy(&tcpaddr, pClientAddr, sizeof(SOCKADDR_IN)); tcpaddr.sin_port = htons(DATA_PORT); //如若有什麼意外只需要在標頭檔案修改埠值 //請求連線使用者端 if (connect(datatcps, (SOCKADDR*)&tcpaddr, sizeof(tcpaddr)) == SOCKET_ERROR) { printf("Connecting to client failed!n"); closesocket(datatcps); return 0; } *pDatatcps = datatcps; return 1; } //處理命令報文 //tcps:控制連線通訊端 //pcmd:指向待處理的命令報文 //pClientAddr:指向使用者端控制連線通訊端地址 //返回值:0表示有錯或者需要結束連線,1正常 int ProcessCmd(SOCKET tcps, CmdPacket* pCmd, SOCKADDR_IN *pClientAddr) { SOCKET datatcps; //資料連線通訊端 RspnsPacket rspns; //回覆報文 FILE* file; //根據命令型別分派執行: switch (pCmd->cmdid) { case LS://展示當前目錄下的檔案列表 //首先建立資料連線: if (!InitDataSocket(&datatcps, pClientAddr)) return 0; //傳送檔案列表資訊: if (!SendFileList(datatcps)) return 0; break; case PWD://展示當前目錄的絕對路徑 rspns.rspnsid = OK; //獲取當前目錄,並放至回覆報文中 if (!GetCurrentDirectory(RSPNS_TEXT_SIZE, rspns.text)) strcpy(rspns.text, "Can't get current dir!n"); if (!SendRspns(tcps, &rspns)) return 0; break; case CD://設定當前目錄,使用win32 API 介面函數 if (SetCurrentDirectory(pCmd->param)) { rspns.rspnsid = OK; if (!GetCurrentDirectory(RSPNS_TEXT_SIZE, rspns.text)) strcpy(rspns.text, "切換當前目錄成功!但是不能獲取到當前的檔案列表!n"); } else { strcpy(rspns.text, "不能更換到所選目錄!n"); } if (!SendRspns(tcps, &rspns)) //傳送回復報文 return 0; break; case DOWN://處理下載檔案請求: file = fopen(pCmd->param, "rb"); //開啟要下載的檔案 if (file) { rspns.rspnsid = OK; sprintf(rspns.text, "下載檔案%sn", pCmd->param); if (!SendRspns(tcps, &rspns)) { fclose(file); return 0; } else { //建立額外的資料連線來傳送資料: if (!InitDataSocket(&datatcps, pClientAddr)) { fclose(file); return 0; } if (!SendFile(datatcps, file)) return 0; fclose(file); } } else //開啟檔案失敗 { rspns.rspnsid = ERR; strcpy(rspns.text, "不能開啟檔案!n"); if (!SendRspns(tcps, &rspns)) return 0; } break; case UP://處理上傳檔案請求 //首先傳送回復報文 char filename[64]; strcpy(filename, pCmd->param); //首先看一下伺服器上是否已經有這個檔案裡,如果有就告訴使用者端不用傳輸了 if (FileExists(filename)) { rspns.rspnsid = ERR; sprintf(rspns.text, "伺服器已經存在名字為%s的檔案!n", filename); if (!SendRspns(tcps, &rspns)) return 0; } else { rspns.rspnsid = OK; if (!SendRspns(tcps, &rspns)) return 0; //另建立一個資料連線來接受資料: if (!InitDataSocket(&datatcps, pClientAddr)) return 0; if (!RecvFile(datatcps, filename)) return 0; } break; case QUIT: printf("使用者端斷開連線。n"); rspns.rspnsid = OK; strcpy(rspns.text, "常來啊!n"); SendRspns(tcps, &rspns); return 0; } return 1; } //傳送回復報文 int SendRspns(SOCKET tcps, RspnsPacket* prspns) { if (send(tcps, (char *)prspns, sizeof(RspnsPacket), 0) == SOCKET_ERROR) { printf("與使用者端失去連線。n"); return 0; } return 1; } //接收命令報文 //tcps:控制連線通訊端 //pCmd:用於儲存返回的命令報文 //返回值:0表示有錯或者連線已經斷開,1表示正常 int RecvCmd(SOCKET tcps, char* pCmd) { //used to receive command from client int nRet; int left = sizeof(CmdPacket); //從控制連線中讀取資料,大小為 sizeof(CmdPacket): while (left) { nRet = recv(tcps, pCmd, left, 0); if (nRet == SOCKET_ERROR) { printf("從使用者端接受命令時發生未知錯誤!n"); return 0; } if (!nRet) { printf("使用者端關閉了連線!n"); return 0; } left -= nRet; pCmd += nRet; } return 1; //成功獲取命令報文 } //傳送一項檔案資訊: int SendFileRecord(SOCKET datatcps, WIN32_FIND_DATA* pfd) { //used to send response to client char filerecord[MAX_PATH + 32]; FILETIME ft; FileTimeToLocalFileTime(&pfd->ftLastWriteTime, &ft); SYSTEMTIME lastwtime; FileTimeToSystemTime(&ft, &lastwtime); char* dir = (char*)(pfd->dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY ? "<DIR>" : ""); sprintf(filerecord, "%04d-%02d-%02d%02d:%02d %5s %10d %-20sn", lastwtime.wYear, lastwtime.wMonth, lastwtime.wDay, lastwtime.wHour, lastwtime.wMinute, dir, pfd->nFileSizeLow, pfd->cFileName); if (send(datatcps, filerecord, strlen(filerecord), 0) == SOCKET_ERROR) { printf("傳送檔案列表時發生未知錯誤!n"); return 0; } return 1; } //傳送檔案列表資訊 //datatcps:資料連線通訊端 //返回值:0表示出錯,1表示正常 int SendFileList(SOCKET datatcps) { HANDLE hff; WIN32_FIND_DATA fd; //搜尋檔案 hff = FindFirstFile("*", &fd); if (hff == INVALID_HANDLE_VALUE) //發生錯誤 { const char* errstr = "不能列出檔案!n"; printf("檔案列表輸出失敗!n"); if (send(datatcps, errstr, strlen(errstr), 0) == SOCKET_ERROR) { printf("傳送給檔案列表時發生未知錯誤!n"); } closesocket(datatcps); return 0; } BOOL fMoreFiles = TRUE; while (fMoreFiles) { //傳送此項檔案資訊: if (!SendFileRecord(datatcps, &fd)) { closesocket(datatcps); return 0; } //搜尋下一個檔案 fMoreFiles = FindNextFile(hff, &fd); } closesocket(datatcps); return 1; } //通過資料連線傳送檔案 int SendFile(SOCKET datatcps, FILE* file) { char buf[1024]; printf("傳送檔案資料中。。。。。。"); for (;;) { //從檔案中迴圈讀取資料並行送使用者端 int r = fread(buf, 1, 1024, file); if (send(datatcps, buf, r, 0) == SOCKET_ERROR) { printf("與使用者端失去連線!n"); closesocket(datatcps); return 0; } if (r < 1024) //檔案傳輸結束 { break; } } closesocket(datatcps); printf("完成傳輸!n"); return 1; } //接收檔案 //datatcps:資料連線通訊端,通過它來接收資料 //filename:用於存放資料的檔名 int RecvFile(SOCKET datatcps, char* filename) { char buf[1024]; FILE* file = fopen(filename, "wb"); if (!file) { printf("寫入檔案時發生未知錯誤!n"); fclose(file); closesocket(datatcps); return 0; } printf("接受檔案資料中。。。。。。"); while (1) { int r = recv(datatcps, buf, 1024, 0); if (r == SOCKET_ERROR) { printf("從使用者端接受檔案時發生未知錯誤!n"); fclose(file); closesocket(datatcps); return 0; } if (!r) { break; } fwrite(buf, 1, r, file); } fclose(file); closesocket(datatcps); printf("完成傳輸!n"); return 1; } //檢測檔案是否存在: int FileExists(const char *filename) { WIN32_FIND_DATA fd; if (FindFirstFile(filename, &fd) == INVALID_HANDLE_VALUE) return 0; return 1; }
3.使用者端
標頭檔案:(sizes.h)
#pragma once //伺服器偵聽控制連線請求的埠 #define CMD_PORT 5858 //客戶機偵聽資料連線請求的埠 #define DATA_PORT 5850 //命令報文引數快取的大小 #define CMD_PARAM_SIZE 256 //回覆報文訊息快取的大小 #define RSPNS_TEXT_SIZE 256 #define BACKLOG 10 #define DATA_BUFSIZE 4096 //命令型別 typedef enum { LS, PWD, CD, DOWN, UP, QUIT } CmdID; //命令報文,從使用者端發往伺服器 typedef struct _CmdPacket { CmdID cmdid; char param[CMD_PARAM_SIZE]; } CmdPacket; //回覆報文的型別 typedef enum { OK, ERR } RspnsID; //回覆報文,從伺服器發往使用者端 typedef struct _RspnsPacket { RspnsID rspnsid; char text[RSPNS_TEXT_SIZE]; } RspnsPacket;
原始檔:(使用者端.cpp)
#include <WinSock2.h> #include <windows.h> #include "sizes.h" #include <tchar.h> #include <iostream> #pragma comment(lib, "ws2_32.lib") //讀取回復報文 void do_read_rspns(SOCKET fd, RspnsPacket *ptr) { int count = 0; int size = sizeof(RspnsPacket); while (count < size) { int nRead = recv(fd, (char *)ptr + count, size - count, 0); if (nRead <= 0) { printf("讀取伺服器的回覆失敗!n"); closesocket(fd); exit(1); } count += nRead; } } //傳送命令報文 void do_write_cmd(SOCKET fd, CmdPacket *ptr) { int size = sizeof(CmdPacket); int flag = send(fd, (char *)ptr, size, 0); if (flag == SOCKET_ERROR) { printf("給伺服器傳送命令失敗!n"); closesocket(fd); WSACleanup(); exit(1); } } //建立資料連線通訊端並進入偵聽狀態 SOCKET create_data_socket() { SOCKET sockfd; struct sockaddr_in my_addr; //建立用於資料連線的通訊端 if ((sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) { printf("建立用於資料連線的通訊端失敗!n"); WSACleanup(); exit(1); } my_addr.sin_family = AF_INET; my_addr.sin_port = htons(DATA_PORT); my_addr.sin_addr.s_addr = htonl(INADDR_ANY); memset(&(my_addr.sin_zero), 0, sizeof(my_addr.sin_zero)); //繫結 if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == SOCKET_ERROR) { int err = WSAGetLastError(); printf("繫結地址失敗,錯誤程式碼:%dn", err); closesocket(sockfd); WSACleanup(); exit(1); } //偵聽資料連線請求 if (listen(sockfd, 1) == SOCKET_ERROR) { printf("監聽資料連線失敗!n"); closesocket(sockfd); WSACleanup(); exit(1); } return sockfd; } //處理list命令 void list(SOCKET sockfd) { int sin_size; int nRead; CmdPacket cmd_packet; SOCKET newsockfd, data_sockfd; struct sockaddr_in their_add; char data_buf[DATA_BUFSIZE]; //建立資料連線 newsockfd = create_data_socket(); //構建命令報文並行送至伺服器 cmd_packet.cmdid = LS;//沒有引數 do_write_cmd(sockfd, &cmd_packet); sin_size = sizeof(struct sockaddr_in); //接受伺服器的資料連線請求 if ((data_sockfd = accept(newsockfd, (struct sockaddr*)&their_add, &sin_size)) == INVALID_SOCKET) { printf("獲取檔案列表失敗!n"); closesocket(newsockfd); closesocket(sockfd); WSACleanup(); exit(1); } //每次讀到多少資料就顯示多少,直到資料連線斷開 while (true) { nRead = recv(data_sockfd, data_buf, DATA_BUFSIZE - 1, 0); if (nRead == SOCKET_ERROR) { printf("讀取伺服器回覆失敗!n"); closesocket(data_sockfd); closesocket(newsockfd); closesocket(sockfd); WSACleanup(); exit(1); } if (nRead == 0)//資料讀取結束 break; //顯示資料 data_buf[nRead] = ' '; printf("%s", data_buf); } closesocket(data_sockfd); closesocket(newsockfd); } //處理pwd命令: void pwd(int sockfd) { CmdPacket cmd_packet; RspnsPacket rspns_packet; cmd_packet.cmdid = PWD; //傳送命令報文並讀取回復: do_write_cmd(sockfd, &cmd_packet); do_read_rspns(sockfd, &rspns_packet); printf("%sn", rspns_packet.text); } //處理cd命令: void cd(int sockfd) { CmdPacket cmd_packet; RspnsPacket rspns_packet; cmd_packet.cmdid = CD; scanf("%s", cmd_packet.param); //傳送命令報文並讀取回復: do_write_cmd(sockfd, &cmd_packet); do_read_rspns(sockfd, &rspns_packet); if (rspns_packet.rspnsid == ERR) printf("%s", rspns_packet.text); } //處理down命令,即下載檔案: void get_file(SOCKET sockfd) { FILE *fd; char data_buf[DATA_BUFSIZE]; CmdPacket cmd_packet; RspnsPacket rspns_packet; SOCKET newsockfd, data_sockfd; struct sockaddr_in their_addr; int sin_size; int count; //設定命令報文: cmd_packet.cmdid = DOWN; scanf("%s", cmd_packet.param); //開啟或者建立本地檔案以供寫資料: fd = fopen(cmd_packet.param, "wb");//使用二進位制方程 if (fd == NULL) { printf("開啟檔案%s來寫入失敗!n", cmd_packet.param); return; } //建立資料連線並偵聽伺服器的連線請求: newsockfd = create_data_socket(); //傳送報文請求: do_write_cmd(sockfd, &cmd_packet); //讀取回復報文: do_read_rspns(sockfd, &rspns_packet); if (rspns_packet.rspnsid == ERR) { printf("%s", rspns_packet.text); closesocket(newsockfd); fclose(fd); //刪除檔案: DeleteFile(cmd_packet.param); return; } sin_size = sizeof(struct sockaddr_in); //等待接受伺服器的連線請求 if ((data_sockfd = accept(newsockfd, (struct sockaddr *)&their_addr, &sin_size)) == INVALID_SOCKET) { printf("獲取檔案失敗!n"); closesocket(newsockfd); fclose(fd); //刪除檔案: DeleteFile(cmd_packet.param); return; } //迴圈讀取網路資料並寫入檔案: while ((count = recv(data_sockfd, data_buf, DATA_BUFSIZE, 0)) > 0) fwrite(data_buf, sizeof(char), count, fd); closesocket(data_sockfd); closesocket(newsockfd); fclose(fd); } //處理put命令,即上傳檔案 void put_file(SOCKET sockfd) { FILE *fd; CmdPacket cmd_packet; RspnsPacket rspns_packet; char data_buf[DATA_BUFSIZE]; SOCKET newsockfd, data_sockfd; struct sockaddr_in their_addr; int sin_size; int count; cmd_packet.cmdid = UP; scanf("%s", cmd_packet.param); //開啟本地檔案用於讀取資料 fd = fopen(cmd_packet.param, "rb"); if (fd == NULL) { printf("開啟檔案%s來讀取資料失敗!n", cmd_packet.param); return; } //建立資料連線通訊端並進入偵聽狀態; newsockfd = create_data_socket(); //傳送命令報文 do_write_cmd(sockfd, &cmd_packet); //讀取回復報文 do_read_rspns(sockfd, &rspns_packet); if (rspns_packet.rspnsid == ERR) { printf("%s", rspns_packet.text); closesocket(newsockfd); fclose(fd); return; } sin_size = sizeof(struct sockaddr_in); //準備接受資料連線 if ((data_sockfd = accept(newsockfd, (struct sockaddr *)&their_addr, &sin_size)) == INVALID_SOCKET) { printf("上傳檔案傳輸錯誤!n"); closesocket(newsockfd); fclose(fd); return; } //迴圈從檔案中讀取資料並行給伺服器 while (true) { count = fread(data_buf, sizeof(char), DATA_BUFSIZE, fd); send(data_sockfd, data_buf, count, 0); if (count < DATA_BUFSIZE)//資料已經讀完或者發生cuowu break; } closesocket(data_sockfd); closesocket(newsockfd); fclose(fd); } //處理退出命令 void quit(int sockfd) { CmdPacket cmd_packet; RspnsPacket rspns_packet; cmd_packet.cmdid = QUIT; do_write_cmd(sockfd, &cmd_packet); do_read_rspns(sockfd, &rspns_packet); printf("%s", rspns_packet.text); getchar(); } void main() { SOCKET sockfd; struct sockaddr_in their_addr; char cmd[10]; RspnsPacket rspns_packet; WORD wVersionRequested; WSADATA wsaData; int err; wVersionRequested = MAKEWORD(2, 2); //Winsock初始化 err = WSAStartup(wVersionRequested, &wsaData); if (err != 0) { printf("WinSock初始化失敗!n"); return; } //確認WindSock DLL的版本是2.2 if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) { printf("WindSock版本不是2.2!n"); WSACleanup(); return; } //建立用於控制諒解的socket sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (sockfd == INVALID_SOCKET) { printf("建立通訊端失敗!n"); WSACleanup(); exit(1); } their_addr.sin_family = AF_INET; their_addr.sin_port = htons(CMD_PORT); their_addr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); memset(&(their_addr.sin_zero), 0, sizeof(their_addr.sin_zero)); //連線伺服器 if (connect(sockfd, (struct sockaddr*)&their_addr, sizeof(struct sockaddr)) == SOCKET_ERROR) { printf("連線伺服器失敗!n"); closesocket(sockfd); WSACleanup(); exit(1); } //連線成功後,首先接受伺服器發回的訊息 do_read_rspns(sockfd, &rspns_packet); printf("%s", rspns_packet.text); //主迴圈:讀取使用者輸入並分配執行 while (true) { scanf("%s", cmd); switch (cmd[0]) { case 'l'://處理List命令 list(sockfd); break; case 'p'://處理pwd命令 pwd(sockfd); break; case 'c'://處理cd命令 cd(sockfd); break; case 'd'://處理down命令 get_file(sockfd); break; case 'u'://處理up命令 put_file(sockfd); break; case 'q'://處理quit命令 quit(sockfd); break; default: printf("不存在的命令!n"); break; } if (cmd[0] == 'q') break; } WSACleanup(); }
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援it145.com。
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45