基于WINSOCK的FTP客户端的实现
用Socket编程实现FTP
格式:int PASCAL FAR select(int nfds,fd_set FAR * readfds,fd_set FAR * writefds, fd_set FAR * exceptfds,const struct timeval FAR * timeout); 参数:readfds:指向要做读检测的指针 writefds:指向要做写检测的指针 exceptfds:指向要检测是否出错的指针 timeout:最大等待时间
连接管理:
数据连接有 3 大用途: (1) 从客户向服务器发送一个文件 (2) 从服务器向客户发送一个文件 (3) 从服务器向客户发送文件或目录列表。
每一个数据连接对传输一个文件或目录序列都要建立一个新的连接。 (1) 客户发出命令要求建立数据连接 (2) 客户在客户主机上未数据连接选择一个固定的端口号 (3) 客户使用 PORT 命令从控制连接上把端口号发给服务器。 (4) 服务器在控制连接上接收端口号,并向客户端主机上的端口发出主动打开,服务器的数据连接 使用端口 21。
服务器端程序则持续的监听网络。当接受到客户端的 Socket ,服务器程序提供相应的服务。网络通 信模块使用 POP3 控件来实现客户端与服务器的信息交流。
函数功能和流程如下:(1)首先创建一个 CFtpclient 的类的实例。 (2)用 LogOnToServer()函数登录到指定的 FTP 服务器,允许非匿名用户和匿名两种登录方式,默认 的端口为 21. (3)使用 MoveFile()函数来上传下载数据文件,其中第一个参数是本地地址,第二个参数是远程地 址,文件传输选用二进制模式。注意,文件传输使用同步模式。 (4)可以使用 Ftpcommand()函数来执行 FTP 指令,包括常用的“CWD/home/mydir”来改变远程服务 器上的地址,并处理服务器返回的应答。当这种方式不适用的时候,还可以使用 WriteStr()函数和 ReadStr() 函数向远程服务器发送指令,并自己解释返回的应答。 (5)当所有的文件传输完成之后,使用 LogOffServer 函数来断开与远程服务器的连接。
FTP服务器C++代码实现
准备工作VC6.0添加ws2_32.lib到工程,如下图操作:1.首先添加winsock库到工程2.添加lib库文件3.添加ws2_32.lib切记用空格隔开4.点击OK即可源代码:FTP_Client:#pragma comment( lib, "ws2_32.lib" )#include <Winsock2.h>#include <iostream.h>#include <stdio.h>#include <fstream.h>#include <string.h>#include <windows.h>#define TRAN_SUCCESS 1 //传输成功#define SOCK_WSA_ERR (-1) //启动winsock库失败#define SOCK_CRSOCK_ERR (-2) //创建套接字失败#define SOCK_BIND_ERR (-3) //绑定端口失败#define SOCK_LISTEN_ERR (-4) //监听失败#define SOCK_ACCEPT_ERR (-5) //等待连接失败#define SOCK_SEND_ERR (-6) //发送数据失败#define SOCK_CLOSE_ERR (-7) //关闭SOCKET失败#define SOCK_RECVE_ERR (-8) //接受数据失败#define SOCK_CONNECT_ERR (-10)#define FILE_ERR (-9) //文件错误#define Other_ERR (0) //其他不明原因#define SVR_PORT 6000 //服务器端口#define SEND_BUFFER_SIZE 4096 //每次发送大小#define RECV_BUFFER_SIZE 4096 //每次发送大小struct Fileinfo{char fileName[50]; //文件名int fileBlock; //文件分块大小int BlockNum; //文件块数量unsigned long fileSize; //文件总大小};int RecevData( SOCKET s );int Client(char* fileName);void PrintReturn(int nRet);int Client( char* strIP)//int Client()//int Client(char* fileName){int nResult = 0;//1、启动Winsock:对Winsock DLL进行初始化,协商Winsock的版本支持并分配必要的资源。
北京理工大学-计算机网络实践-FTP客户端实验报告
实验五 FTP客户端程序1.实验目的文件传送协议FTP是Internet中广泛使用的服务协议之一,FTP协议是客户/服务器之间进行文件传递的协议。
●理解FTP协议的工作原理●掌握FTP客户程序的编程方法●理解在FTP传输过程中建立的两个连接2.实验内容利用WinSock编程接口编写FTP客户程序,在用户界面中给出必要的FTP 服务器信息:FTP服务器的IP地址、用户名、口令等,通过FTP协议实现指定文件的上载和下载操作。
3.实验环境程序运行环境为以太网,采用TCP/IP协议栈,网络操作系统为Windows,具有Internet连接能力。
程序开发环境为vs2012。
4.实验步骤步骤1 需求分析FTP客户程序功能为:(1) FTP客户程序首先显示用户界面,可以指定FTP服务器的地址、用户名和口令等信息(2)通过FTP协议接收FTP服务器的当前目录列表,并显示本地和远程目录列表信息(3)可以实现本地和远程目录的切换(4)可以实现文件的上载和下载操作步骤2 FTP客户程序开发用Visual C++编写FTP客户程序,利用WinSock编程接口实现FTP协议通信。
FTP客户程序首先显示用户界面,使用户可以指定FTP服务器和用户、口令信息(可以采用匿名方式),点击连接按钮后,向FTP服务器的TCP 21号端口建立TCP连接,在控制连接上发送FTP命令,首先获得本地和远程系统的目录列表并显示,可以进行目录切换等操作,指定上、下载的文件建立数据连接进行文件传送。
步骤3 编译和执行程序将FTP客户程序编译、连接成执行程序,运行FTP客户程序。
填写校园网的FTP服务器IP和用户、口令信息,进行各种FTP操作(文件上载、下载)。
5.具体实现(1)数据结构分析定义FileItem结构来保存文件信息typedef struct FileItem{int nItem; // 在列表框中的索引BOOL bDir; // 判断是否为文件夹CString strFileName; // 文件名}FILEITEM;主对话框类完成FTP的大部分功能其中:ID_control成员变量:CListCtrl m_ctrlRemoteFiles; // IDC_LIST_REMOTE 映射的列表型变量CListCtrl m_ctrlLocalFiles; // IDC_LIST_LOCAL 映射的列表型变量CString m_strPassword; // IDC_PASSWORD 映射的CString型变量CString m_strServer; // IDC_SERVER 映射的CString型变量CString m_strUserName; // IDC_USER 映射的CString型变量其他添加功能所需成员变量:CInternetSession* m_pInetSession; // 会话对象CFtpConnection* m_pFtpConnection; // 连接对象CFtpFileFind* m_pRemoteFinder; // 远程查找文件对象CFileFind m_LocalFinder; // 本地查找文件对象CString m_strLocalParentRoot; // 本地文件目录的上上一层目录CString m_strRemoteParentRoot; // 远程文件目录的上上一层目录CArray<FILEITEM,FILEITEM&>m_arrLocalFiles; // 保存本地文件信息CArray<FILEITEM,FILEITEM&>m_arrRemoteFiles; // 保存远程文件信息 成员函数:/* 初始化程序 */BOOL CMyFtpDlg::OnInitDialog()/* 给列表控件CListCtrl增加标题头 */void CMyFtpDlg::AddHeaders(CListCtrl* pLstCtrl)/* 给列表框增加一条记录 */void CMyFtpDlg::AddItem(CListCtrl* pLstCtrl,int nIndex,BOOL bDir,CString strText)/* 响应“download”按钮 */void CMyFtpDlg::OnDownload()/* 响应“Upload”按钮 */void CMyFtpDlg::OnUpload()/* 下载单个文件 */void CMyFtpDlg::DownFile(FILEITEM fileItem)/* 上传单个文件 */void CMyFtpDlg::UpFile(FILEITEM fileItem)/* 连接ftp服务器 */void CMyFtpDlg::OnConnect()/* 获得指定目录下的所有文件,并在列表框中显示 */void CMyFtpDlg::BrowseDir(CString strDir,CListCtrl* pLstCtrl,CFileFind* pFinder,CArray<FILEITEM,FILEITEM&>* pFilesArr)/* 本地文件目录中向上一层 */void CMyFtpDlg::OnLocalUp()/* 远程文件目录中向上一层 */void CMyFtpDlg::OnRemoteUp()主要函数1.在OnInitDialog()函数中进行对话框、列表的初始化,并且设定本地文件目录的默认路径为C盘为根目录。
FTP客户端和服务器源代码(C语言)实现
课程设计:FTP的设计与实现/****************client.c****************/#include <winsock2.h>#include <stdio.h>#include <stdlib.h>#pragma comment(lib,"ws2_32.lib")#define DEFAULT_PORT 2302#define DEFAULT_BUFFER 2048#define DEFAULT_MESSAGE "This is a test of the emergency \ broadcasting system" char szServerip[128], // Server to connect toszMessage[1024]; // Message to send to severint iPort = DEFAULT_PORT; // Port on server to connect to//DWORD dwCount = DEFAULT_COUNT; // Number of times to send message BOOL bSendOnly = FALSE; // Send data only; don't receiveint dirfun();int getfun();int putfun();int pwdfun();int cdfun();int mdfun();int delfun();int usafun();void usage(){printf("usage: client [-p:x] [-s:IP] [-n:x] [-o]\n\n");printf(" -p:x Remote port to send to\n");printf(" -s:IP Server's IP address or hostname\n");printf(" -n:x Number of times to send message\n");printf(" -o Send messages only; don't receive\n");ExitProcess(1);}void ValidateArgs(int argc, char **argv){int i;for(i = 1; i < argc; i++){if ((argv[i][0] == '-') || (argv[i][0] == '/')){switch (tolower(argv[i][1])){case 'p': // Remote portif (strlen(argv[i]) > 3)iPort = atoi(&argv[i][3]);break;case 's': // Serverif (strlen(argv[i]) > 3)strcpy(szServerip, &argv[i][3]);break;case 'n': // Number of times to send messageif (strlen(argv[i]) > 3)//dwCount = atol(&argv[i][3]);break;case 'o': // Only send message; don't receive bSendOnly = TRUE;break;default:usage();break;}}}}int main(int argc, char **argv){WSADATA wsd;SOCKET sClient;char szBuffer[DEFAULT_BUFFER];int ret;//unsigned int i;//int j;struct sockaddr_in server;struct hostent *host = NULL;char choice[5],choice2[40];// Parse the command line and load Winsock//argv[1]="-s:127.0.0.1";strcpy(szServerip, &argv[1][3]);//ValidateArgs(argc, argv);if (WSAStartup(MAKEWORD(2,2), &wsd) != 0){printf("Failed to load Winsock library!\n");return 1;}//strcpy(szMessage, DEFAULT_MESSAGE);// Create the socket, and attempt to connect to the server//sClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (sClient == INVALID_SOCKET){printf("socket() failed: %d\n", WSAGetLastError());return 1;}server.sin_family = AF_INET;server.sin_port = htons(iPort);printf("server.sin_port=%u\n",server.sin_port);server.sin_addr.s_addr = inet_addr(szServerip);//// If the supplied server address wasn't in the form// "c.ddd" it's a hostname, so try to resolve it//if (server.sin_addr.s_addr == INADDR_NONE){host = gethostbyname(szServerip);if (host == NULL){printf("Unable to resolve server: %s\n", szServerip);return 1;}CopyMemory(&server.sin_addr, host->h_addr_list[0],host->h_length);}if (connect(sClient, (struct sockaddr *)&server,sizeof(server)) == SOCKET_ERROR){printf("connect() failed: %d\n", WSAGetLastError());return 1;}//显示接通信息//////for(j=0;j<2;j++)//{ret = recv(sClient, szBuffer, DEFAULT_BUFFER, 0);if (ret == 0) // Graceful closereturn 0;else if (ret == SOCKET_ERROR)printf("recv() failed: %d\n", WSAGetLastError());return 0;}szBuffer[ret] = '\0';printf("%s\n",szBuffer);if(ret<15){ret = recv(sClient, szBuffer, DEFAULT_BUFFER, 0);if (ret == 0) // Graceful closereturn 0;else if (ret == SOCKET_ERROR){//printf("recv() failed: %d\n", WSAGetLastError());return 0;}szBuffer[ret] = '\0';printf("%s\n",szBuffer);}//printf("DEFAULT_BUFFER=%d\n",DEFAULT_BUFFER);}while(1){puts("------------------------------------------");printf("ftp> ");scanf("%s", choice);if(strncmp(choice,"dir",3)==0||strncmp(choice,"DIR",2)==0){dirfun(sClient);continue;}else if(strncmp(choice,"pwd",3)==0||strncmp(choice,"PWD",3)==0) {pwdfun(sClient);continue;}else if(strncmp(choice,"?",1)==0){usafun(sClient);continue;else if(strncmp(choice,"quit",4)==0||strncmp(choice,"QUIT",2)==0) {break;}scanf("%s", choice2);if(strncmp(choice,"get",3)==0||strncmp(choice,"GET",3)==0){getfun(sClient,choice2);continue;}else if(strncmp(choice,"put",3)==0||strncmp(choice,"PUT",3)==0) {putfun(sClient,choice2);continue;}else if(strncmp(choice,"cd",2)==0||strncmp(choice,"CD",2)==0){cdfun(sClient,choice2);continue;}else if(strncmp(choice,"md",2)==0||strncmp(choice,"MD",2)==0){mdfun(sClient,choice2);continue;}else if(strncmp(choice,"del",3)==0||strncmp(choice,"DEL",3)==0){delfun(sClient,choice2);continue;}//elseputs("输入错误,请重新输入");fflush(stdin);fflush(stdin);printf("\n");printf("\n");}closesocket(sClient);WSACleanup();}int dirfun(SOCKET sClient){int ret;char *MSG="dir$";char szBuffer[80];strcpy(szMessage, MSG);ret = send(sClient, szMessage, strlen(szMessage), 0);if (ret == 0)return 1;else if (ret == SOCKET_ERROR){printf("send() failed: %d\n", WSAGetLastError());return 1;}//printf("Send %d bytes\n", ret);//printf("bSendOnly=%d\n",bSendOnly);while(!bSendOnly){//读取流并显示//ret = recv(sClient, szBuffer, 80, 0);//printf("%s",szBuffer);ret = recv(sClient, szBuffer, 80, 0);if (ret == 0) // Graceful closereturn 1;else if (ret == SOCKET_ERROR){printf("recv() failed: %d\n", WSAGetLastError());return 1;}szBuffer[ret] = '\0';if(strncmp(szBuffer,"226 Close",strlen("226 Close"))==0){break;}printf("%s",szBuffer);if(strncmp(szBuffer,"500 Syntax error",strlen("500 Syntax error"))==0){break;}return 0;}int getfun(SOCKET sClient,char filename[40]){int ret;FILE *fpre;char szBuffer[80];szMessage[0]='\0';strcat(szMessage, "get$");//strcat(szMessage, "\\");strcat(szMessage,filename);//printf("MSG[4]=%c\n",szMessage[4]);//szMessage[0]='g';szMessage[1]='e';szMessage[2]='t';////szMessage[4]='m';szMessage[5]='e';szMessage[6]='.';szMessage[7]='t';////szMessage[8]='x';szMessage[9]='t';szMessage[10]='\0';ret = send(sClient, szMessage, strlen(szMessage)+1, 0);if (ret == 0)return 1;else if (ret == SOCKET_ERROR){printf("send() failed: %d\n", WSAGetLastError());return 1;}printf("Send %d bytes\n", ret);ret = recv(sClient, szBuffer, 80, 0);/*if (ret == 0) // Graceful closebreak;else if (ret == SOCKET_ERROR){printf("recv() failed: %d\n", WSAGetLastError());break;}*/szBuffer[ret] = '\0';printf("%s\n",szBuffer);if(strncmp( szBuffer,"125 Transfering...",strlen("125 Transfering...") )==0) {if( (fpre=fopen(filename,"w")) == NULL ){printf("open errer");return 1;printf("bSendOnly=%d\n",bSendOnly);while(!bSendOnly){//读取流并显示ret = recv(sClient, szBuffer, 80, 0);if (ret == 0) // Graceful closereturn 1;else if (ret == SOCKET_ERROR){printf("recv() failed: %d\n", WSAGetLastError());return 1;}szBuffer[ret] = '\0';//printf("%s",szBuffer);if(strncmp(szBuffer,"226 Transfer",strlen("226 Transfer"))==0){break;}if(strncmp(szBuffer,"500 Syntax error",strlen("500 Syntax error"))==0){break;}fprintf(fpre,"%s",szBuffer);}printf("%s\n",szBuffer);fclose(fpre);}return 0;}int putfun(SOCKET sClient,char filename[40]){int ret;//int i;FILE *fpse;//char *filename;//char *MSG="get\0me.txt";char szBuffer[80],temp_buffer[80];//sprintf(szMessage, "get\0","te.txt\0");szMessage[0]='\0';strcat(szMessage, "put$");strcat(szMessage,filename);ret = send(sClient, szMessage, strlen(szMessage)+1, 0);if (ret == 0)return 0;else if (ret == SOCKET_ERROR){printf("send() failed: %d\n", WSAGetLastError());return 1;}//printf("Send %d bytes\n", ret);//filename="me.txt";printf("filename=%s\n",filename);if( (fpse=fopen(filename,"r")) == NULL ){printf("open errer");return 1;}else{printf("The file %s found,ready to transfer.\n",filename);//i=0;while (fgets(temp_buffer,80,fpse)!=NULL){sprintf(szBuffer,"%s",temp_buffer);send(sClient, szBuffer, 80, 0);}}sprintf(szBuffer, "226 Transfer completed... \r\n");ret = send(sClient, szBuffer, strlen(szBuffer), 0);fclose(fpse);return 0;}int pwdfun(SOCKET sClient){int ret;char *MSG="pwd$";char szBuffer[160];strcpy(szMessage, MSG);ret = send(sClient, szMessage, strlen(szMessage), 0);if (ret == 0)return 1;else if (ret == SOCKET_ERROR){printf("send() failed: %d\n", WSAGetLastError());return 1;}printf("Send %d bytes\n", ret);printf("bSendOnly=%d\n",bSendOnly);while(!bSendOnly){//读取流并显示ret = recv(sClient, szBuffer, 160, 0);if (ret == 0) // Graceful closereturn 1;else if (ret == SOCKET_ERROR){printf("recv() failed: %d\n", WSAGetLastError());return 1;}szBuffer[ret] = '\0';printf("%s\n",szBuffer);if(strncmp(szBuffer,"226 Close",strlen("226 Close"))==0){break;}if(strncmp(szBuffer,"500 Syntax error",strlen("500 Syntax error"))==0) {break;}}return 0;}int cdfun(SOCKET sClient,char pathname[40]){int ret;szMessage[0]='\0';strcat(szMessage, "cd$");strcat(szMessage,pathname);ret = send(sClient, szMessage, strlen(szMessage)+1, 0);if (ret == 0)return 1;else if (ret == SOCKET_ERROR){printf("send() failed: %d\n", WSAGetLastError());return 1;}printf("Send %d bytes\n", ret);return 0;}int mdfun(SOCKET sClient,char pathname[20]){int ret;char szBuffer[160];//char *MSG="md$";szMessage[0]='\0';strcat(szMessage, "md$");//strcat(szMessage, "\\");strcat(szMessage,pathname);//strcpy(szMessage, MSG);ret = send(sClient, szMessage, strlen(szMessage)+1, 0);if (ret == 0)return 1;else if (ret == SOCKET_ERROR){printf("send() failed: %d\n", WSAGetLastError());return 1;}printf("Send %d bytes\n", ret);while(!bSendOnly){//读取流并显示ret = recv(sClient, szBuffer, 80, 0);if (ret == 0) // Graceful closereturn 1;else if (ret == SOCKET_ERROR){printf("recv() failed: %d\n", WSAGetLastError());return 1;}szBuffer[ret] = '\0';printf("%s",szBuffer);if(strncmp(szBuffer,"226 Close",strlen("226 Close"))==0){break;}if(strncmp(szBuffer,"500 Syntax error",strlen("500 Syntax error"))==0){break;}}return 0;}int delfun(SOCKET sClient,char name[20]){int ret;char szBuffer[80];szMessage[0]='\0';strcat(szMessage, "del$");strcat(szMessage,name);ret = send(sClient, szMessage, strlen(szMessage)+1, 0);if (ret == 0)return 1;else if (ret == SOCKET_ERROR){printf("send() failed: %d\n", WSAGetLastError());return 1;}printf("Send %d bytes\n", ret);while(!bSendOnly){ret = recv(sClient, szBuffer, 80, 0);if (ret == 0) // Graceful closereturn 1;else if (ret == SOCKET_ERROR){printf("recv() failed: %d\n", WSAGetLastError());return 1;}szBuffer[ret] = '\0';if(strncmp(szBuffer,"del ok",strlen("del ok"))==0){printf("del %s ok\n",name);break;}printf("%s",szBuffer);if(strncmp(szBuffer,"500 Syntax error",strlen("500 Syntax error"))==0) {break;}}return 0;}int usafun(){puts("------------------------------------------");puts("get:取远方的一个文件");puts("put:传给远方一个文件");puts("pwd:显示远主当前目录");puts("dir:列出远方当前目录");puts("md :在远方新建文件夹");puts("cd :改变远方当前目录");puts("?:显示你提供的命令");puts("quit :退出返回");return 0;}//int quit()/****************server.c****************/#include <stdio.h>#include <winsock.h>#include <stdlib.h>#pragma comment(lib,"ws2_32.lib")WSADATA wsd;char sbuffer[80],rbuffer[80];//send and receive buffersint n,bytes;//countersSOCKET newsocket,ns_data;struct sockaddr_in remoteaddr; //remoteaddr_data;int port_connect=0;//port connect flagchar path[80]="";char order[100]="";//SOCKET s_data_port;int sy_error=1; // use for indicate Syntax error//server functionsint sdirfun(SOCKET newsocket);int sgetfun(SOCKET newsocket);int sputfun(SOCKET newsocket);int spwdfun(SOCKET newsocket);int scdfun(SOCKET newsocket);int smdfun(SOCKET newsocket);int sdelfun(SOCKET newsocket);void HandleError(char *func);//server functions end//MAINint main(int argc, char *argv[]){struct sockaddr_in localaddr;//local address structureSOCKET s;//s_data;//welcome socket and welcome socket for data connection,and port connection for connect to clientint addr_inlen;//address lenght variableif (WSAStartup(MAKEWORD(2,2), &wsd) != 0){WSACleanup();printf("WSAStartup failed\n");}memset(&localaddr,0,sizeof(localaddr));//clear localaddrs = socket(PF_INET, SOCK_STREAM, 0);if (s <0){printf("socket failed\n");}localaddr.sin_family = AF_INET;if(argc == 2)localaddr.sin_port = htons((u_short)atoi(argv[1]));elselocaladdr.sin_port = htons(2302);localaddr.sin_addr.s_addr = INADDR_ANY;if (bind(s,(struct sockaddr *)(&localaddr),sizeof(localaddr)) < 0){printf("Bind failed!\n");}//INFINITE LOOPwhile (1){ // while loop 1//LISTENlisten(s,3);addr_inlen = sizeof(remoteaddr);//ACCEPT main connection (control connection)newsocket = accept(s,(struct sockaddr *)(&remoteaddr),&addr_inlen);if (newsocket == INVALID_SOCKET) break;printf("connected to %s at port %d \n",inet_ntoa(remoteaddr.sin_addr),ntohs(localaddr.sin_port));//Respond with welcome message, FTP client requires thosesprintf(sbuffer,"200 Welcome \r\n");bytes = send(newsocket, sbuffer, strlen(sbuffer), 0);sprintf(sbuffer,"530 Log in \r\n");bytes = send(newsocket, sbuffer, strlen(sbuffer), 0);//INFINITE LOOPwhile (1) // while loop 2{n = 0;sy_error=1;while (1) // while loop 3{//RECEIVEbytes = recv(newsocket, &rbuffer[n], 1, 0);printf("rbuffer[%d]=%c\n",n,rbuffer[n]);if ((bytes < 0) || (bytes == 0))break;if (rbuffer[n] == '$'){rbuffer[n] = '\0';break;}if (rbuffer[n] != '\r')n++;} // end of while loop 3if ((bytes < 0) || (bytes == 0))break;printf("#The Server receives:# '%s' from client \n", rbuffer); //THE FTP COMMANDS HERE//LISTif(strncmp(rbuffer,"dir",3)==0){sdirfun(newsocket);}//当前目录if(strncmp(rbuffer,"pwd",3)==0){spwdfun(newsocket);}//改变目录if (strncmp(rbuffer,"cd",2)==0){scdfun(newsocket);}//GETif (strncmp(rbuffer,"get",3)==0){sgetfun(newsocket);}//PUTif (strncmp(rbuffer,"put",3)==0){sputfun(newsocket);}//MDif (strncmp(rbuffer,"md",2)==0){smdfun(newsocket);}if (strncmp(rbuffer,"del",3)==0){sdelfun(newsocket);}//QUITif (strncmp(rbuffer,"quit",4)==0){printf("quit \n");sprintf(sbuffer, "221 Bye bye ... \r\n");bytes = send(newsocket, sbuffer, strlen(sbuffer), 0);sy_error=0;break;}//Syntax errorif (sy_error==1){printf("command unrecognized, non-implemented!\n");sprintf(sbuffer, "500 Syntax error. \n");bytes = send(newsocket, sbuffer, strlen(sbuffer), 0);}} // end of while loop 2//CLOSE CONTROL SOCKETclosesocket(newsocket);printf("disconnected from %s at port %d, close control socket.\n",inet_ntoa(remoteaddr.sin_addr),ntohs(localaddr.sin_port));} // end of while loop 1//CLOSE WELCOME SOCKETclosesocket(s);printf("Welcome sockets close");return 0;}int sdirfun(SOCKET newsocket){char temp_buffer[80];printf("Equivalent to dir \n");order[0]='\0';strcat(order,"dir ");strcat(order,path);strcat(order," >tmp.txt");system(order);FILE *fin;fin=fopen("tmp.txt","r");sprintf(sbuffer, "125 Transfering... \r\n");bytes = send(newsocket, sbuffer, strlen(sbuffer), 0);while (fgets(temp_buffer,80,fin)!=NULL){sprintf(sbuffer,"%s",temp_buffer); //if (port_connect==0)send(newsocket, sbuffer, strlen(sbuffer), 0);}fclose(fin);sprintf(sbuffer, "226 Transfer completed... \r\n");bytes = send(newsocket, sbuffer, strlen(sbuffer), 0);system("del tmp.txt");//CLOSE the ns_data SOCKET or data port SOCKETif(port_connect==0){closesocket(ns_data);sprintf(sbuffer,"226 Close the data socket... \r\n");bytes = send(newsocket, sbuffer, strlen(sbuffer), 0);ns_data = socket(AF_INET, SOCK_STREAM, 0);}sy_error=0;return 0;}int sgetfun(SOCKET newsocket){printf("RETR mode.\r\n");int i=4,k=0;char filename[20],temp_buffer[80];// identify the filename from rbuffer after the word "RETR "while (1) // while loop 4{//RECEIVEbytes = recv(newsocket, &rbuffer[i], 1, 0);printf("rbuffer[i]=%c\n",rbuffer[i]);if ((bytes < 0) || (bytes == 0))break;filename[k]=rbuffer[i];if (rbuffer[i] == '\0'){ /*end on LF*/filename[k] = '\0';break;}if (rbuffer[i] != '\r'){i++;k++;/*ignore CR's*/}} // end of while loop 4order[0]='\0';strcat(order,path);if(strlen(path)>0)strcat(order,"\\");strcat(order,filename);char *p_filename=order;FILE *fp;if( (fp=fopen(p_filename,"r")) == NULL ){sprintf(sbuffer, "Sorry, cannot open %s. Please try again.\r\n",filename);bytes = send(newsocket, sbuffer, strlen(sbuffer), 0);sprintf(sbuffer, "226 Transfer completed... \r\n");bytes = send(newsocket, sbuffer, strlen(sbuffer), 0);return 1;}else{printf("The file %s found,ready to transfer.\n",filename);sprintf(sbuffer, "125 Transfering... \r\n");bytes = send(newsocket, sbuffer, strlen(sbuffer), 0);while (fgets(temp_buffer,80,fp)!=NULL){sprintf(sbuffer,"%s",temp_buffer); //if (port_connect==0)send(newsocket, sbuffer, strlen(sbuffer), 0);}//end of whilefclose(fp);sprintf(sbuffer, "226 Transfer completed... \r\n");bytes = send(newsocket, sbuffer, strlen(sbuffer), 0);}sy_error=0;return 0;}int sputfun(SOCKET newsocket){printf("Equivalent to put. \n");int i=4,k=0;char filename[20];// identify the filename from rbuffer after the word "RETR "while (1){bytes = recv(newsocket, &rbuffer[i], 1, 0);if ((bytes < 0) || (bytes == 0))break;filename[k]=rbuffer[i];if (rbuffer[i] == '\0'){ /*end on LF*/filename[k] = '\0';break;}if (rbuffer[i] != '\r'){i++;k++;/*ignore CR's*/}} // end of whileorder[0]='\0';strcat(order,path);if(strlen(path)>0)strcat(order,"\\");strcat(order,filename);printf("filename=%s,",order);char *p_filename=order;FILE *fpse;if( (fpse=fopen(order,"w")) == NULL ){printf("open errer");return 1;}else{printf("The file %s found,ready to transfer.\n",filename);while(1){//读取流并显示int ret;ret = recv(newsocket, rbuffer, 80, 0);if (ret == 0) // Graceful closereturn 0;else if (ret == SOCKET_ERROR){printf("recv() failed: %d\n", WSAGetLastError());return 0;}if(strncmp(rbuffer,"226 Transfer",strlen("226 Transfer"))==0){break;}fprintf(fpse,"%s",rbuffer);}printf("RBUFFER=%s",rbuffer);fclose(fpse);}sy_error=0;return 0;}int spwdfun(SOCKET newsocket){printf("Equivalent to pwd \n");//order[0]='\0';//strcat(order,"dir ");//strcat(order,path);//strcat(order,);system("cd >tmp.txt");FILE *fin;fin=fopen("tmp.txt","r+");sprintf(sbuffer, "125 Transfering... \r\n");bytes = send(newsocket, sbuffer, strlen(sbuffer), 0);char temp_buffer[160];while (fgets(temp_buffer,80,fin)!=NULL){temp_buffer[strlen(temp_buffer)-1]='\0';printf("temp_buffer=%s",temp_buffer);///////////////////////////////目录判定if(path[0]!='\0')sprintf(sbuffer,"%s\\%s",temp_buffer,path);elsesprintf(sbuffer,"%s",temp_buffer);///////////////////////////////if (port_connect==0)//send(ns_data, sbuffer, strlen(sbuffer), 0);send(newsocket, sbuffer, strlen(sbuffer), 0);}fclose(fin);sprintf(sbuffer, "226 Transfer completed... \r\n");bytes = send(newsocket, sbuffer, strlen(sbuffer), 0);system("del tmp.txt");//CLOSE the ns_data SOCKET or data port SOCKETif(port_connect==0){closesocket(ns_data);sprintf(sbuffer,"226 Close the data socket... \r\n");bytes = send(newsocket, sbuffer, strlen(sbuffer), 0);ns_data = socket(AF_INET, SOCK_STREAM, 0);}sy_error=0;return 0;}int scdfun(SOCKET newsocket){int i=3,k=0;char name[20],name2[20];int j,count=0;//path overfollowint pathlen;printf("Equivalent to cd \n");while (1){//RECEIVEbytes = recv(newsocket, &rbuffer[i], 1, 0);printf("rbuffer[i]=%c\n",rbuffer[i]);printf("bytes=%d\n",bytes);if ((bytes < 0) || (bytes == 0))break;name[k]=rbuffer[i];name2[k]=rbuffer[i];if (rbuffer[i] == '\0'){name[k] = '\0';name2[k] = '\0';break;}if (rbuffer[i] != '\r'){i++;k++;}}//end whileif(path[0]!='\0')strcat(path,"\\");strcat(path,name);if(strncmp(name2,"..",2)==0){pathlen=strlen(path);for(j=pathlen-1;j>=0;j--){if(path[j]=='\\'){path[j]='\0';count++;}if(count==2){//path[j]='\0';break;}}printf("%d=\n",j);path[j+1]='\0';}printf("path=%s",path);sy_error=0;return 0;}int smdfun(SOCKET newsocket){char name[20];int i=3,k=0;printf("Equivalent to md \n");while (1) // while loop 3{//RECEIVEbytes = recv(newsocket, &rbuffer[i], 1, 0);printf("rbuffer[i]=%c\n",rbuffer[i]);printf("bytes=%d\n",bytes);if ((bytes < 0) || (bytes == 0))break;name[k]=rbuffer[i];if (rbuffer[i] == '\0'){ /*end on LF*/name[k] = '\0';break;}if (rbuffer[i] != '\r'){i++;k++;/*ignore CR's*/}}order[0]='\0';strcat(order,"md ");strcat(order,path);if(strlen(path)>0)strcat(order,"\\");strcat(order,name);system(order);//CLOSE the ns_data SOCKET or data port SOCKETif(port_connect==0){//closesocket(ns_data);sprintf(sbuffer,"226 Close the data socket... \r\n");bytes = send(newsocket, sbuffer, strlen(sbuffer), 0);//ns_data = socket(AF_INET, SOCK_STREAM, 0);}sy_error=0;return 0;}int sdelfun(SOCKET newsocket){int i=3,k=0;char name[20];printf("Equivalent to del \n");while (1){//RECEIVEbytes = recv(newsocket, &rbuffer[i], 1, 0);printf("rbuffer[i]=%c\n",rbuffer[i]);printf("bytes=%d\n",bytes);if ((bytes < 0) || (bytes == 0))break;name[k]=rbuffer[i];if (rbuffer[i] == '\0'){name[k] = '\0';break;}if (rbuffer[i] != '\r'){i++;k++;}}//end whileorder[0]='\0';strcat(order,"rd ");strcat(order,path);if(path[0]!='\0')strcat(path,"\\");strcat(order,name);system(order);sprintf(sbuffer,"del ok... \r\n");bytes = send(newsocket, sbuffer, strlen(sbuffer), 0);if (bytes == SOCKET_ERROR){HandleError("recv()");sy_error=1;return 1;}sy_error=0;return 0;}void HandleError(char *func){char info[65]= {0};_snprintf(info, 64, "%s: %d\n", func, WSAGetLastError());printf(info);}。
基于WINSOCK的FTP客户端的实现
基于Winsock的FTP客户端的实现目录一、课程设计基本要求 (2)课程设计目的 (2)课程设计任务 (2)课程设计要求 (2)二、程序简介 (2)开发环境 (2)程序界面 (3)三、原理概述 (4)FTP协议 (4)应用WinSock实现网络通信 (5)四、主要数据结构 (6)五、CFTPClient类 (8)控制连接的实现 (8)数据连接的实现 (11)六、体会 (13)一、课程设计基本要求●课程设计目的1 加深对TCP/IP协议的理解。
2 了解FTP协议的工作原理。
3 掌握用MFC编写FTP协议的实现程序。
●课程设计任务在Visual C++6.0的环境下实现FTP下载工具。
●课程设计要求1 了解FTP协议的工作原理。
(RFC765 , RFC2228, RFC2640, RFC2773)2 主要是基于TCP/IP的Winsock编程,用Visual C++6.0实现一个基于FTP协议的FTP下载工具(客户端)。
二、程序简介●开发环境操作系统:Microsoft Windows XP pro编译环境:Microsoft Visual C++ 6.0CPU:PM-1.7GHz内存:768MB硬盘:40MB分辨率:32bit 1024×768 程序界面三、原理概述FTP协议FTP是Internet上基于TCP/IP协议传输文件的应用层协议。
FTP规定了数据包的格式、数据包头部结构和命令结构等等。
FTP应用命令行方式传输文件。
FTP在RFC959中定义。
FTP应用TCP传输而不是UDP。
由FTP提供的文件传输是将一个完整的文件从一个系统复制到另一个系统中。
应用FTP首先需要登录FTP服务器,或者通过允许匿名FTP来使用FTP服务器。
FTP最早的设计是用于两台不同的主机即不同的操作系统下,不同的文件结构,不同的字符集。
FTP是建立两个TCP连接(见图) ,一个用于传输数据,另一个用于传输命令。
FTP客户端的设计与实现
FTP客户端的设计与实现1. 简介FTP(File Transfer Protocol)是一种用于文件传输的标准协议。
FTP客户端是指使用FTP协议与FTP服务器进行通信并传输文件的程序。
在本文中,我们将探讨FTP客户端的设计与实现。
2. 设计2.1 功能需求FTP客户端的主要功能需求包括:1.连接到FTP服务器2.在FTP服务器和本地电脑之间传输文件3.列出FTP服务器上的文件和目录4.创建和删除FTP服务器上的目录5.重命名FTP服务器上的文件6.支持多种操作系统(如Windows、Linux等)2.2 架构设计FTP客户端采用MVC(Model-View-Controller)模式来设计,其中:•Model层:管理FTP客户端的业务与数据逻辑。
提供FTP相关的API,封装了FTP协议的底层实现。
•View层:处理和呈现用户界面。
•Controller层:处理用户请求,调用Model层实现相关业务逻辑。
2.3 技术选型FTP客户端的技术选型如下:•编程语言:Java•GUI框架:JavaFX•FTP库:Apache Commons Net•构建工具:Maven•版本控制:Git2.4 待解决问题FTP客户端在设计中会遇到以下问题:1.如何扩展支持更多的FTP协议?2.如何实现可靠的文件传输?3.如何提高用户界面的体验?3. 实现3.1 界面实现使用JavaFX框架实现FTP客户端的用户界面。
主要界面包括:•登录界面:输入FTP服务器地址、用户名和密码登录FTP服务器。
•主界面:显示FTP服务器上的文件和目录,并提供文件传输和操作的操作界面。
3.2 功能实现FTP客户端通过Apache Commons Net库实现FTP底层协议。
实现的功能包括:1.连接到FTP服务器FTPClient ftp = new FTPClient();ftp.connect(server, port);ftp.login(username, password);2.在FTP服务器和本地电脑之间传输文件ftp.retrieveFile(remoteFile, localFile);ftp.storeFile(remoteFile, localFile);3.列出FTP服务器上的文件和目录FTPFile[] files = ftp.listFiles(remoteDir);4.创建和删除FTP服务器上的目录ftp.mkd(remoteDir);ftp.rmd(remoteDir);5.重命名FTP服务器上的文件ftp.rename(from, to);4. 总结通过对FTP客户端的设计与实现,我们了解了FTP协议的底层实现和FTP客户端的主要功能。
最新电子信息科学与技术专业_毕业论文可选题目汇总5
m号指标;论文类说明创新点174光电传感器特性实验平台的研制光电传感器特性实验平台主要针对温州大学《感测技术》课程实验所设计的,其功能为:使用某种传感器与实验平台组成一个闭环系统,能够设定并控制转速大小,可以用来测试光电传感器的一些特性。
转速测量范围:0~2000转/分;频率测量范围:0~1MHz 较强的自学习能力,C,单片机知识,模拟电路知识设计175公交车语音报站器的设计应用于公交系统,提示乘客到站,极大方便了乘客。
主要利用存储语音资源和LED键盘显示模块完整地播放一条公交线路的站名,并且能够显示日期和时间,具有时间日期的设置功能。
①制作硬件电路并实现功能。
②通过按键选择到站语音提示,声音大小的调整,语音功率驱动电路。
③显示站台编号,设置和显示当前日期和时间。
显示时间,日期;声音调整;语言提示。
较强的自学习能力,C,单片机知识,模拟电路知识设计176 冲击大电流的产生与应用利用RLC振荡电路产生100-1000A,约50Hz大电流,利用单片机控制流程应用于校验断路器短路电流的瞬时特性.并与传统的方法进行比较.电流误差5%,总功率500W以内单片机,模电,电力电子设计177高功率因素电子镇流器的研发利用L6562有源功率因数修正芯片将220VAC变换成400VDC,再利用DC-AC变换制作40W高功率因素电子镇流器.学习不同场合电感的设计与制作功率因素0.95以上,效率85%以上模电,电力电子,磁性材料设计号指标;论文类说明创新点科研(《感测技术》课程教学改革的探索与实践)教师自拟(智能化仪器仪表)教师自拟教师自拟。
Windows server 2003搭建ftp服务器步骤
Windows server 2003搭建ftp服务器步骤参考,客户端使用主动模式(Windows server 2003 32/64位)在Windows下搭建ftp服务器可以使用系统自带的ftp服务。
以32 位的Windows server 2003为例,具体步骤如下:第一步:安装ftp服务a. 将i386文件拷贝到服务器上或插入Windows2003安装光盘b. 单击“开始-控制面板-添加或删除程序-添加/删除Windows组件”选项c. 在“组件”列表中,双击“应用程序服务器”选项,单击并选中“Internet 信息服务(IIS)”选项,然后单击“详细信息”按钮,打开“应用程序服务器子组件”窗口。
d. 选中“文件传输协议(FTP) 服务”这个选项,单击确定。
以上步骤如图1所示。
图1e. 单击“下一步”按钮。
出现提示时,如需要文件i386,则定位到刚才拷贝的i386文件,一直点下一步,最后点完成。
第二步:配置ftp站点a. 点击开始-管理工具-Internet 信息服务管理器,如图2所示。
图2b. 右键新建站点,点击下一步,填写FTP 站点描述,如图3。
图3c. 配置IP和端口,也可以选择默认的设置,点击下一步。
如图4。
图4d. 配置FTP用户隔离,选择隔离用户。
如图5。
图5e. 选择FTP的根目录,我在此C盘下新建了一个tmp目录,用它来做ftp的根目录。
设置好之后点击下一步,如图6。
图6f. 配置FTP站点的访问权限,点击下一步。
出现图7所示的界面。
出现这样的提示是因为我们的默认ftp站点是打开的,这个不用管它,点完成就可以了。
图7g. IIS 管理器的界面上,关掉FTP的默认站点,再在tmp站点上右键,点启动,就启动了新建的站点。
如图8。
图8f. 在tmp站点上右键,选择属性,可以配置tmp站点的属性.在这里可以设置ftp的站点目录以及站点目录的访问属性、是否允许匿名登录等属性。
如图9所示。
FTP客户端的设计与实现
FTP客户端的设计与实现摘要FTP是Internet上用来传送文件的协议。
它是为了我们能够在Internet上互相传送文件而制定的文件传送标准,规定了Internet上文件如何传送.通过FTP协议,我们就可以跟Internet上的FTP服务器进行文件的上传或下载。
本设计以实现一个简单易用的FTP客户端为目标,通过分析FTP协议的基本工作原理和FTP的数据传输原理,研究如何使用VC++语言对FTP客户端进行设计,用Visual Studio2010设计和实现了FTP客户端的开发。
关键词FTP的工作原理;VC++;FTP客户端1绪论1。
1 课题背景FTP是互联网上使用最广泛的文件传输协议[1].在互联网早期曾占据整个互联网通信的三分之一,它解决了在不同操作系统下处理文件格式的不兼容性。
传统方式需要在DOS 下输入命令,对于普通用户是件极困难的事。
但有了FTP客户端软件后,只要轻点几下鼠标就可以完成所有操作。
FTP客户端应该包含以下功能:登录,浏览目录,上传和下载[2]。
它已成为人们不可缺少的软件之一.1。
2 研究现状FTP服务是Internet上最早应用于主机之间进行数据传输的基本服务之一。
起初,FTP 并不是应用于IP网络上的协议,而是20世纪60~80年代美国国防部组建的ARPANET网络中,用于计算机间的文件传输的协议。
FTP服务的一个非常重要的特点是其实现可以独立于平台,也就是说在UNIX、DOS、Windows等操作系统中都可以实现FTP的客户端和服务器[3]。
尽管目前已经普遍采用HTTP方式传送文件,但FTP仍然是跨平台直接传送文件的主要方式。
目前市面上可通过正规渠道获得的成熟的FTP软件如Server-U、Cuteftp、Transmit、Flashfxp等都是国外开发的,需要注册、付费使用。
从其他渠道获取的FTP软件,则存在安全方面的问题。
国内也很难找到免费、安全的FTP软件。
虽然操作系统有自带的FTP软件,但它是基于命令行的,没有友好的用户操作界面,对用户的计算机技能要求较高,一般的用户也不会用,而且不支持断点续传和文件夹的上传、下载等功能[4]。
用VBWinsock控件创建TCPIP客户机服务器程序
用VBWinsock控件创建TCPIP客户机/服务器程序摘要本文介绍了如何使用VBWinsock控件来创建基于TCP/IP协议的客户机/服务器程序。
通过VBWinsock控件,我们可以通过互联网或局域网上的计算机之间进行通信。
本文将分为以下几个部分来说明如何创建并使用VBWinsock控件来实现客户机/服务器应用程序。
1.VBWinsock控件是Visual Basic的一个强大的网络编程控件,用于与其他计算机进行网络通信。
它通过提供一系列的事件和方法,使得我们可以轻松地创建客户机/服务器应用程序。
2. 创建服务器端程序要创建一个服务器端程序,我们需要首先添加VBWinsock控件到我们的项目中。
进入Visual Basic的设计界面,单击“工具箱”窗口上的“组件”选项卡,然后选择VBWinsock控件,拖放到我们的窗体或模块中。
现在我们可以开始编写服务器端程序的代码。
以下是一个简单的VBWinsock服务器端程序的示例:Private Sub Form_Load()Winsock1.LocalPort = 5000 ' 设置服务器监听的端口号Winsock1.Listen ' 启动服务器监听End SubPrivate Sub Winsock1_ConnectionRequest(ByVal requestID As Long) If Winsock1.State <> sckClosed ThenWinsock1.Close ' 如果当前有连接,则关闭它End IfWinsock1.Accept requestID ' 接受客户端的连接请求End SubPrivate Sub Winsock1_DataArrival(ByVal bytesTotal As Long) Dim receivedData As StringWinsock1.GetData receivedData ' 接收数据' 处理接收到的数据End Sub在上述代码中,我们首先在Form_Load()事件中设置了服务器监听的端口号。
Serv-u安全配置详细完整版
Serv-u安全配置详细完整版最近在网上看到一篇写serve u的文章写的不错,特地转过来与大家一起学习一、Serv-U安全隐患及利用。
二、Serv-U安装及安全设置详解。
三、Serv-U相关的模式与防火墙设置。
四、关于Serv-U的Banner及登录消息的设置。
Serv-U是一款十分经典的FTP服务器软件,一直被大部分管理员和虚拟主机所使用,它简单的安装和配置以及强大的管理功能也一直被管理员们称颂。
但是随着使用者越来越多,也有越来越多的主机被通过Serv-U软件所入侵。
本文旨在提出一些切实可行的方法,彻底杜绝由Serv-U带来的安全隐患。
1、Serv-U的安装:关于Serv-U的安装网上许多文章中提到要安装在一个复杂的路径,个人认为这个不是十分必要,完全可以按照你喜欢的例如:D:\soft\Serv-U目录里。
但是不推荐安装在系统盘目录里,也不推荐安装在c:\Program files目录里,因为这个目录的权限的原因(详细权限设置以后再发文专门讨论)。
推荐的方式是无需安装,直接使用绿色版的或直接复制在其他机器上安装好的Serv-U的目录。
Serv-U的用户配置文件有两种方式,一种是存放在注册表,一种是存放在ServUDaemon.ini文件,推荐使用存放在.ini文件里面的方式,这种方式便于ser-u软件的升级,也便于重装系统后的ftp用户的恢复,在权限设置上也相对方便。
我们这里使用6.4.0.6版,推荐使用,这里我们假设Serv-U软件放在的的D:\soft\Serv-U目录里。
2、权限设置:给Serv-U单独的用户权限运行。
在计算机管理中新增帐户ftp,设置用户不能更改密码,密码用不过期,并设置一个复杂的密码,更改ftp用户隶属于Guests组(默认是USERS组),当然也可以设置为不属于任何组。
启动Serv-U(这时是使用默认的system权限运行的),选择本地服务器,自动开始,将Serv-U设置为系统服务,这样服务器在每次重启时Serv-U就会自动启动,这里我们主要利用其可以在服务中配置给Serv-U单独用户。
FTP客户端C++版
(1)头文件:FTPClient.h#include<conio.h>#define MAX_SIZE 4096#include<iostream>#include<winsock2.h>#include<string>#include<fstream>#pragma comment(lib,"ws2_32.lib")using namespace std;class FTPClient{public:bool RecvReply(); //控制连接接收bool SendCommand(); //向FTP服务器发送命令bool DataConnect(char* ServerAddr); //向FTP服务器发送命令bool mkdirectory(); //FTP服务器发送MKD命令bool changedir(); //FTP服务器发送CWD命令bool FTPConnection(char* FTPIP,int port); //建立与Socket库绑定bool useuser(); //向FTP服务器发送USER命令bool usepass(); //向FTP服务器发送PASS命令void subcommend(string& filepath,string& filename); //输入和转换IP地址void storfile(char* FTPIP); //上传文件void retrfile(char* FTPIP); //下载文件void listftp(char* FTPIP); //列出FTP服务器目录void deletefile(); //删除文件void quitftp(); //退出客户端void help(); //帮助void about(); //aboutbool ishavedetail;char CmdBuf[MAX_SIZE];char Command[MAX_SIZE];char ReplyMsg[MAX_SIZE];private:int nReplycode;bool bConnected;bool buser;SOCKET SocketControl;SOCKET SocketData;};(2)源文件:FTPClient.cpp#include<conio.h>#define MAX_SIZE 4096#include<iostream>#include<winsock2.h>#include<string>#include<fstream>#include"FTPClient.h"using namespace std;#pragma comment(lib,"ws2_32.lib")bool FTPClient::RecvReply() //控制连接接收{int nRecv;memset(ReplyMsg, 0, MAX_SIZE);nRecv = recv(SocketControl, ReplyMsg, MAX_SIZE, 0);if (nRecv == SOCKET_ERROR){cout <<"Socket receive error!"<< endl;closesocket(SocketControl);return false;}//获取相应信息与响应码if (nRecv > 4){char *ReplyCodes = new c har[3];memset(ReplyCodes, 0, 3);memcpy(ReplyCodes, ReplyMsg, 3);nReplycode = atoi(ReplyCodes);}return true;}bool FTPClient::SendCommand() //向FTP服务器发送命令{//控制连接发送数据int nSend;nSend = send(SocketControl, Command, strlen(Command), 0);if (nSend == SOCKET_ERROR){cout <<"Socket send error!"<< endl;return false;}return true;}bool FTPClient::DataConnect(char* ServerAddr){//向FTP服务器发送PASV命令memset(Command, 0, MAX_SIZE);memcpy(Command, "PASV", strlen("PASV"));memcpy(Command + strlen("PASV"), "\r\n", 2);if (!SendCommand())return false;//获取PASV命令的应答信息if (RecvReply()){if (nReplycode != 227){cout <<"PASV response error!"<< endl;closesocket(SocketControl);return false;}}//分离PASV命令应答信息char* part[6];if (strtok(ReplyMsg, "(")){for (int i = 0; i < 5; i++){part[i] = strtok(NULL, ",");if (!part[i])return false;}part[5] = strtok(NULL, ")");if (!part[5])return false;}else{return false;}//获取FTP服务器数据端口、unsigned short ServerPort;ServerPort = unsigned short((atoi(part[4]) << 8) + atoi(part[5]));//创建数据连接SocketSocketData = socket(AF_INET, SOCK_STREAM, 0);if (SocketData == INVALID_SOCKET){cout <<"Create socket error!"<< endl;return false;}//定义Socket地址和端口sockaddr_in serveraddr2;memset(&serveraddr2, 0, sizeof(serveraddr2));serveraddr2.sin_family = AF_INET;serveraddr2.sin_port = htons(ServerPort);serveraddr2.sin_addr.S_un.S_addr = inet_addr(ServerAddr);//向FTP服务器发送Connect请求int nConnect;nConnect = connect(SocketData, (sockaddr*)&serveraddr2, sizeof(serveraddr2));if (nConnect == SOCKET_ERROR){cout << endl <<"Server connect error!"<< endl;return false;}return true;}bool FTPClient::mkdirectory() //FTP服务器发送MKD命令{if (!ishavedetail){cout <<"请输入你要创建的文件夹名:";memset(CmdBuf, 0, MAX_SIZE);cin.getline(CmdBuf, MAX_SIZE, '\n');}memset(Command, 0, MAX_SIZE);memcpy(Command, "MKD ", strlen("MKD "));memcpy(Command + strlen("MKD "), CmdBuf, strlen(CmdBuf));memcpy(Command + strlen("MKD ") + strlen(CmdBuf), "\r\n", 2);//cout<<"Command:"<<Command<<endl;if (!SendCommand())return false;//-----------获得MKD命令的应答信息------------------------if (RecvReply()){if (nReplycode == 257)//257:cout << ReplyMsg << endl;else{cout <<"MKD response error!"<< endl;closesocket(SocketControl);return false;}}return true;}bool FTPClient::changedir() //FTP服务器发送CWD命令{if (!ishavedetail){cout <<"请输入你要进入的文件夹路径:";memset(CmdBuf, 0, MAX_SIZE);cin.getline(CmdBuf, MAX_SIZE, '\n');}memset(Command, 0, MAX_SIZE);memcpy(Command, "CWD ", strlen("CWD "));memcpy(Command + strlen("CWD "), CmdBuf, strlen(CmdBuf));memcpy(Command + strlen("CWD ") + strlen(CmdBuf), "\r\n", 2);if (!SendCommand())return false;//-----------获得CWD命令的应答信息------------------------if (RecvReply()){cout <<"nReplyCode:"<< nReplycode << endl;if (nReplycode == 250)//257:cout << ReplyMsg << endl;else{cout <<"CWD response error!"<< endl;closesocket(SocketControl);return false;}}return true;}bool FTPClient::FTPConnection(char* FTPIP, int port) //建立与Socket库绑定{WSADATA WSAData; //WSADAT:WSADATA结构被用来储存调用AfxSocketInit全局函数返回的Windows Sockets初始化信息if (WSAStartup(MAKEWORD(2, 2), &WSAData) != 0) //WSAStartup:初始化当前线程通信环境 MAKEWORD:合并短整数{cout <<"WSAStartup error!"<< endl;return false;}//创建控制连接SocketSocketControl = socket(AF_INET, SOCK_STREAM, 0);if (SocketControl == INVALID_SOCKET){cout <<"Creat socket error!"<< endl;return false;}//定义Socket地址和端口sockaddr_in serveraddr;memset(&serveraddr, 0, sizeof(serveraddr));serveraddr.sin_family = AF_INET;//serveraddr.sin_port = htons(port);//端口serveraddr.sin_addr.S_un.S_addr = inet_addr(FTPIP);//地址//向FTP服务器发送Connect请求cout <<"FTP>Control connect..."<< endl;int nConnect = connect(SocketControl, (sockaddr*)&serveraddr, sizeof(serveraddr));if (nConnect == SOCKET_ERROR){cout <<"Server connect error!"<< endl;return false;}//获得Connect应答信息if (RecvReply()){if (nReplycode == 220)cout << ReplyMsg << endl;else{cout <<"Connet response error!"<< endl;closesocket(SocketControl);return false;}}bConnected = true;return true;}bool FTPClient::useuser() //向FTP服务器发送USER命令{cout <<"FTP>用户名:";memset(CmdBuf, 0, MAX_SIZE);cin.getline(CmdBuf, MAX_SIZE, '\n');memset(Command, 0, MAX_SIZE);memcpy(Command, "USER ", strlen("USER "));memcpy(Command + strlen("USER "), CmdBuf, strlen(CmdBuf));memcpy(Command + strlen("USER ") + strlen(CmdBuf), "\r\n", 2);cout <<"Command:"<< Command << endl;if (!SendCommand())return false;//获得USER命令的应答信息if (RecvReply()){if (nReplycode == 331)//230:User logged in,proceed;//331:User Name okay,need password;cout << ReplyMsg << endl;else{cout <<"USER response error!"<< endl;closesocket(SocketControl);return false;}}buser = true;return true;}bool FTPClient::usepass() //向FTP服务器发送PASS命令{if (buser){buser = false;cout <<"FTP>密码:";memset(CmdBuf, 0, MAX_SIZE);cout.flush();for (int i = 0; i < MAX_SIZE; i++){CmdBuf[i] = getch();if (CmdBuf[i] == '\r'){CmdBuf[i] = '\0';break;}elsecout <<'*';}cout << endl;memset(Command, 0, MAX_SIZE);memcpy(Command, "PASS ", strlen("PASS "));memcpy(Command + strlen("PASS "), CmdBuf, strlen(CmdBuf));memcpy(Command + strlen("PASS ") + strlen(CmdBuf), "\r\n", 2);if (!SendCommand())return false;//获得PASS命令的应答信息if (RecvReply()){if (nReplycode == 230)//230:User logged in,proceed;cout << ReplyMsg << endl;else{cout <<"PASS respanse error!"<< endl;return false;}}return true;}}void FTPClient::storfile(char* FTPIP){if (!ishavedetail){cout <<"请输入上传文件名:";memset(CmdBuf, 0, MAX_SIZE);cin.getline(CmdBuf, MAX_SIZE, '\n');}ifstream f2;f2.open(CmdBuf, ios::in);if (!f2){cout <<"Cannot open file!"<< endl;return;}string strPath(CmdBuf);string filepath, filename;int nPos = strPath.rfind('\\');if (-1 != nPos){filename = strPath.substr(nPos + 1, strPath.length() - nPos - 1);filepath = strPath.substr(0, nPos);cout <<"filename:"<< filename << endl;cout <<"filepath:"<< filepath << endl;memset(CmdBuf, 0, MAX_SIZE);memcpy(CmdBuf, filename.data(), strlen(filename.data()));}char FtpStor[MAX_SIZE];memset(FtpStor, 0, MAX_SIZE);memcpy(FtpStor, FTPIP, strlen(FTPIP));if (!DataConnect(FtpStor))return;memset(Command, 0, MAX_SIZE);memcpy(Command, "STOR ", strlen("STOR "));memcpy(Command + strlen("STOR "), CmdBuf, strlen(CmdBuf));memcpy(Command + strlen("STOR ") + strlen(CmdBuf), "\r\n", 2);if (!SendCommand()){return;}if (RecvReply()){if (nReplycode == 125 || nReplycode == 150 || nReplycode == 226) cout << ReplyMsg;else {cout <<"STOR respanse error!"<< endl;closesocket(SocketControl);return;}}char ListBuf2[MAX_SIZE];while (true){memset(ListBuf2, 0, MAX_SIZE);f2.read(ListBuf2, MAX_SIZE);int nStor = send(SocketData, ListBuf2, MAX_SIZE, 0);if (nStor == SOCKET_ERROR){cout << endl <<"Socket send error!"<< endl;closesocket(SocketData);return;}break;}f2.close();closesocket(SocketData);if (RecvReply()){if (nReplycode == 226)cout << ReplyMsg;else{cout <<"STOR response error!"<< endl;closesocket(SocketControl);return;}}}void FTPClient::retrfile(char* FTPIP){if (!ishavedetail){cout <<"请输入下载文件名:"<< endl;memset(CmdBuf, 0, MAX_SIZE);cin.getline(CmdBuf, MAX_SIZE, '\n');}char FtpRetr[MAX_SIZE];memset(FtpRetr, 0, MAX_SIZE);memcpy(FtpRetr, FTPIP, strlen(FTPIP));if (!DataConnect(FtpRetr)){return;}memset(Command, 0, MAX_SIZE);memcpy(Command, "RETR ", strlen("RETR "));memcpy(Command + strlen("RETR "), CmdBuf, strlen(CmdBuf));memcpy(Command + strlen("RETR ") + strlen(CmdBuf), "\r\n", 2);cout <<"请输入保存的文件名:";memset(CmdBuf, 0, MAX_SIZE);cin.getline(CmdBuf, MAX_SIZE, '\n');if (!SendCommand())return;if (RecvReply()){cout <<"nReplyCode:"<< nReplycode;if (nReplycode == 125 || nReplycode == 150 || nReplycode == 226) cout << ReplyMsg;else {cout <<"RETR respanse error!"<< endl;closesocket(SocketControl);return;}}ofstream f1(CmdBuf);if (!f1){cout <<"file can not open"<< endl;return;}int nRetr;char ListBuf1[MAX_SIZE];while (true){memset(ListBuf1, 0, MAX_SIZE);nRetr = recv(SocketData, ListBuf1, MAX_SIZE, 0);f1.write(ListBuf1, MAX_SIZE);if (nRetr == SOCKET_ERROR){cout << endl <<"Socket receive error!"<< endl;closesocket(SocketData);return;}if (nRetr <= 0)break;}f1.close();closesocket(SocketData);if (RecvReply()){if (nReplycode == 226){cout << ReplyMsg;}else{cout <<"RETR response error!"<< endl;closesocket(SocketControl);return;}}}void FTPClient::listftp(char* FTPIP) //列出FTP服务器目录{//FTP服务器发送LIST命令char FtpServer[MAX_SIZE];memset(FtpServer, 0, MAX_SIZE);memcpy(FtpServer, FTPIP, strlen(FTPIP));if (!DataConnect(FtpServer))//数据连接{return;}memset(Command, 0, MAX_SIZE);memcpy(Command, "LIST", strlen("LIST"));memcpy(Command + strlen("LIST"), "\r\n", 2);if (!SendCommand()){return;}//--------------获得LIST命令的应答信息-------------------------if (RecvReply()){//125:Data connection alreadly open;transfer staring.//150:File status okay, about to data connection;//226: closing data connection;//150:Opening ASCII mode data connection for /bin/ls;if (nReplycode == 125 || nReplycode == 150 || nReplycode == 226)cout << ReplyMsg;else {cout <<"LIST respanse error!"<< endl;closesocket(SocketControl);return;}}//获得LIST命令的目录信息int nRecv;char ListBuf[MAX_SIZE];while (true){memset(ListBuf, 0, MAX_SIZE);nRecv = recv(SocketData, ListBuf, MAX_SIZE, 0);if (nRecv == SOCKET_ERROR){cout << endl <<"Socket receive error!"<< endl;closesocket(SocketData);return;}if (nRecv <= 0)break;cout << ListBuf;}closesocket(SocketData);//--------------获得LIST命令的应答信息-------------------------------if (RecvReply()){if (nReplycode == 226)//226: closing data connection;transfer complete;cout << ReplyMsg;else{cout <<"LIST response error!"<< endl;closesocket(SocketControl);return;}}}void FTPClient::deletefile() //{if (!ishavedetail){cout <<"请输入你要删除的文件名:";memset(CmdBuf, 0, MAX_SIZE);cin.getline(CmdBuf, MAX_SIZE, '\n');}memset(Command, 0, MAX_SIZE);memcpy(Command, "DELE ", strlen("DELE "));memcpy(Command + strlen("DELE "), CmdBuf, strlen(CmdBuf));memcpy(Command + strlen("DELE ") + strlen(CmdBuf), "\r\n", 2);if (!SendCommand())return;//-----------获得DELE命令的应答信息------------------------if (RecvReply()){if (nReplycode == 250)//230:User logged in,proceed;//331:User Name okay,need password;cout << ReplyMsg << endl;else{cout <<"DELE response error!"<< endl;closesocket(SocketControl);return;}}}void FTPClient::quitftp(){//-------------向FTP服务器发送QUIT命令-------------------------------memset(Command, 0, MAX_SIZE);memcpy(Command, "QUIT", strlen("QUIT"));memcpy(Command + strlen("QUIT"), "\r\n", 2);if (!SendCommand())return;//-------------获得QUIT命令的应答信息--------------------------------if (RecvReply()){if (nReplycode == 221)//221:goodbay,closing session;{cout << ReplyMsg;bConnected = false;//buser=false;closesocket(SocketControl);return;}else{cout << endl <<"QUIT response error!"<< endl;closesocket(SocketControl);return;}}WSACleanup();}void FTPClient::subcommend(string& filepath, string& filename) //输入和转换IP地址{memset(CmdBuf, 0, MAX_SIZE);cin.getline(CmdBuf, MAX_SIZE, '\n');string strPath(CmdBuf);int nPos = strPath.rfind(' ');if (-1 != nPos){filename= strPath.substr(nPos + 1, strPath.length() - nPos - 1);filepath= strPath.substr(0, nPos);}else{filepath= CmdBuf;}}void FTPClient::about(){cout <<"------------关于FTP客户端控制台版-------------"<< endl;cout << endl;cout <<"程序名称:FTP客户端控制台版"<< endl;cout <<"程序语言:C++"<< endl;cout <<"小组成员:刘锐翊杨润牟林李良俊陈秋燕毛虹"<< endl;cout <<"编译日期:2015年12月30日"<< endl;cout << endl;cout <<"----------------------------------------------"<< endl;cout << endl;}void FTPClient::help(){cout <<"------------FTP客户端控制台版帮助-------------"<< endl;cout << endl;cout <<"ls 列出所有目录与文件"<< endl;cout <<"stor 上传文件"<< endl;cout <<"retr 下载文件"<< endl;cout <<"dele 删除文件"<< endl;cout <<"mkd 创建文件"<< endl;cout <<"cwd 进入指定目录"<< endl;cout <<"help 帮助"<< endl;cout <<"about 关于本程序"<< endl;cout << endl;cout <<"----------------------------------------------"<< endl;cout << endl;}(3)源文件:FTPMain.cpp#include"FTPClient.h"#include<iostream>using namespace std;void main(int argc, char* argv[]){SetConsoleTitleA("FTP客户端控制台版 v1.1");FTPClient ftp; //定义FTP对象//检查命令行参数if (argc != 2){cout <<"请输入FTP服务器IP地址:";string a,b;ftp.subcommend(a,b);while(!( const_cast<char*>(a.c_str()))){cout<<"连接失败!请检查输入是否正确!"<<endl;ftp.subcommend(a,b);}if(ftp.FTPConnection(const_cast<char*>(a.c_str()),21)){bool flag;do{euser();flag=epass();}while(!flag);cout <<"提示:help命令可获取帮助!"<<endl;cout <<endl;while(true){cout<<"FTP>";string order,detail;ftp.subcommend(order,detail);if(detail.length()!=0){memset(ftp.CmdBuf,0,MAX_SIZE);memcpy(ftp.CmdBuf,detail.data(),detail.length());ftp.ishavedetail=true;}if(order=="ls")ftp.listftp(const_cast<char*>(a.c_str()));else if(order=="stor")ftp.storfile(const_cast<char*>(a.c_str()));else if(order=="retr")ftp.retrfile(const_cast<char*>(a.c_str()));else if(order=="cwd")ftp.changedir();else if(order=="mkd")ftp.mkdirectory();else if(order=="help")ftp.help();else if(order=="dele")ftp.deletefile();else if(order=="about")ftp.about();else if(order=="quit"){ftp.quitftp();break;}else if(order=="user"){bool flag;do{euser();flag=epass();}while(!flag);}else{cout <<"FTP>无此命令!帮助请输入help!"<<endl;}ftp.ishavedetail=false;}}}}。
《网络编程技术课程设计》论文:FTP客户端设计与实现
上传下载 4
客户端上传或下载选择的文件
传输控制 5
客户端可暂停、恢复和终止文件传输
文件传输模块是FTP客户端的核心功能模块。该模块负责管理与服务端的数据连接、处理文件传输请求、提供传输控制等功能。整个传输过程从连接建立、登录验证、目录浏 览到文件上传下载,客户端需要与服务端进行多次交互来完成。同时,客户端还需要提供传输控制功能,以便用户能够灵活地管理传输任务。
FTP 协议是最常用的文件传输协 议之一, 被广泛应用于各种网络 应用中。
教学需求
本课程设计旨在帮助学生深入理解和掌握网络编程技术, 并能够独立设计 和实现一个 FTP 客户端应用程序。
课程设计目标
实现FTP客户端功能
本课程设计的主要目标是开发 一个功能全面的FTP客户端软 件,实现文件上传、下载、浏 览等基本功能。
下载文件 2
从FTP服务器下载指定文件至本地
断点续传 3
支持大文件的断点续传功能
传输监控 4
实时显示文件传输进度和速度 FTP客户端的核心功能是文件的上传和下载。客户端应支持选择本地文件上传至FTP服务器,并可从服务器下载指定文件至本地。为了提高传输效率和 用户体验,客户端还应实现断点续传功能,并在传输过程中实时显示进度和速度信息。
FTP客户端设计与实现
针对网络编程技术课程设计,本文重点探讨了FTP客户端的设计和实现。FTP是 当前广泛应用的文件传输协议,能够满足用户在各种场景下的文件传输需求。
by
课程设计背景
网络编程技术的重要性
网络编程技术是现代软件开发 的基础, 能够赋予应用程序跨平 台、跨地域的能力。
FTP 协议应用广泛
FTP客户端的系统架构采用模块化设计,包括用户界面模块、文件 传输模块、登录认证模块、目录浏览模块等。各模块之间通过标 准接口进行解耦,提高了系统的灵活性和可扩展性。 系统架构还考虑了异常处理、任务管理和历史记录等功能模块,确 保客户端具有良好的可用性和可靠性。
基于winsock的双机通信接字编程
基于winsock的双机通信接字编程双机通信指的是两台计算机之间相互传输数据的过程。
接下来,我们将介绍如何使用Winsock编写基于TCP协议的双机通信程序。
Winsock是Windows Socket的缩写,是Windows平台上进行网络编程的API 标准。
Winsock提供一组函数和结构体,用于编写网络应用程序,例如创建套接字、发送和接收数据等操作。
以下是基于Winsock的双机通信程序的示例代码:c#include <winsock2.h>#include <stdio.h>int main(){WSADATA wsaData;SOCKET s;SOCKADDR_IN addr;int port = 1234;char buf[256];初始化Winsockif (WSAStartup(MAKEWORD(2,2), &wsaData) != 0) {printf("WSAStartup failed!\n");return 1;}创建套接字s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (s == INVALID_SOCKET){printf("socket failed!\n");WSACleanup();return 1;}地址设置addr.sin_family = AF_INET;addr.sin_port = htons(port);addr.sin_addr.s_addr = htonl(INADDR_ANY);绑定套接字if (bind(s, (SOCKADDR*)&addr, sizeof(addr)) == SOCKET_ERROR) {printf("bind failed!\n");closesocket(s);WSACleanup();return 1;}监听套接字if (listen(s, SOMAXCONN) == SOCKET_ERROR){printf("listen failed!\n");closesocket(s);WSACleanup();return 1;}printf("Waiting for connection...\n");接受连接请求SOCKET clientSocket;SOCKADDR_IN clientAddr;int addrlen = sizeof(clientAddr);clientSocket = accept(s, (SOCKADDR*)&clientAddr, &addrlen);if (clientSocket == INVALID_SOCKET){printf("accept failed!\n");closesocket(s);WSACleanup();return 1;}printf("Connected to %s:%d.\n", inet_ntoa(clientAddr.sin_addr), ntohs(clientAddr.sin_port));发送消息while (1){printf("Enter message: ");fgets(buf, sizeof(buf), stdin);if (send(clientSocket, buf, strlen(buf), 0) == SOCKET_ERROR){printf("send failed!\n");closesocket(clientSocket);WSACleanup();return 1;}if (strcmp(buf, "exit\n") == 0) 输入exit退出循环break;}关闭套接字closesocket(clientSocket);closesocket(s);清理Winsock环境WSACleanup();return 0;}以上代码实现了一个基于Winsock的TCP服务端,它监听特定的端口,并等待客户端连接。
Winsock编程:基于TCPIP协议的TELNET实现
目录摘要1 课程设计目的 (1)2 课程设计要求 (1)3 相关知识 (1)4 课程设计分析 (1)5 程序代码 (3)6 运行结果与分析 (5)7 参考文献 (5)1 课程设计目的学会用基于TCP/IP协议的TELNET实现2课程设计要求① TCP(传输控制协议)提供虚电路和面向连接的数据流传输服务。
实现无差错无重复的顺序数据传输。
②UDP(用户数据报协议)提供无连接的数据报传输服务。
数据通过相互独立的报文进行传输,是无序的,并且不保证可靠、无差错。
3相关知识WinSock操作模式:①同步模式或阻塞模式(blocking mode)采用DOS技术编程,某些WinSock函数(同步函数)直到完成操作后才返回。
例,当执行数据接收函数revc()时,一直等待对方发送数据,直到接收到数据后才返回。
②异步模式或非阻塞模式(non-blocking mode)采用Windows技术编程,利用消息(事件驱动)的特点,使同步函数变为异步函数(不产生阻塞)。
关键:异步选择函数WSAAsyncSelect()的使用。
WSAAsyncSelect()可设置一个或多个网络事件消息,如,已收到数据、数据发送完毕、客户机请求连接、服务器已完成连接等网络事件。
当设置的网络事件发生时,Windows应用程序的窗口函数将收到一个消息。
通过这个消息就可以进行相应的处理。
③套接口SocketSocket 实际上是一个通信端口;一个Socket是通讯的一端。
网络通信将通过各自的Socket相联系。
在应用开发中就像使用文件句柄一样,应用程序向操作系统申请,由操作系统分配本地唯一的Socket端口号。
然后,可以对Socket句柄进行读,写操作。
④.主机地址标识网络环境中的唯一通信端点标识。
包含:协议、IP地址、端口。
(俗称三元组)4课程设计分析服务器首先启动,通过调用socket()建立一个套接口,然后bind()将该套接口和本地地址(IP地址和端口)联系在一起,服务器调用recv()等待接收数据。
Networks课程设计指导书
Network+课程设计指导书周泓江苏淮阴工学院计算机工程系二OO九年九月十日目录一、Network+课程设计的目的 (1)二、实验环境与教学要求 (1)三、实施原则、方案与步骤 (1)四、设计课题 (2)(一)课题综述 (2)(二)参考书目 (4)五、课程设计报告要求 (5)六、成绩评定 (5)七、附录 (5)一、Network+课程设计的目的《Network+》是计算机科学与技术专业软件工程方向重要的一门专业基础课,内容庞大,涉及面广,知识点多,教、学难度都非常大,往往费了大量时间而达不到预期教学效果。
俗语说:学习的最好方法是实践。
本课程设计正是基于此,力求为学生提供一个理论联系实际的机会,通过实践使学生了解网络设计的整体情况,掌握网络需求分析的方法,熟悉主体方案设计(网络规划: 网络构架及拓扑、设备选型及布线规划、IP地址规划,系统软件规划:操作系统及开发工具、网络服务) 的原理和方法;学习文档编写规范,培养独立学习、吸取他人经验、探索前言知识的习惯。
同时,课程设计可以充分弥补课堂教学及普通实验中知识深度与广度有限的缺陷,更好地帮助学生从全局角度把握课程体系。
二、实验环境与教学要求要求实验室配备相关编程语言如:C、C++、C#、Java等语言的开发环境。
要求教师在正确理解课程教学大纲的基础上,结合课题体系的实际需求及学生的实践能力、工作条件等外部因素,选择恰当的设计课题,既体现教学目的,又能反映实际教学情况。
要求保证充足的实践课时,最好配备专职指导教师。
要求同学们:1.要充分认识Network+课程设计的重要性,认真做好各项准备工作;2.既要虚心接受老师的指导,又要充分发挥主观能动性,要结合课题,独立思考,努力钻研,勤于实践,勇于创新;3.收集资料,自学相关知识,拓宽知识面,根据课题的基本要求,自行完成设计任务。
4.要按时、独立完成规定的工作任务,不弄虚作假,不抄袭他人;5.严格遵守学习和劳动纪律,不无故缺席,不迟到早退,不懈怠,不拖拉,要积极主动;6.严格要求自己,树立严肃、严密、严谨的科学态度,按时、按质、按量完成。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
基于Winsock的FTP客户端的实现目录一、课程设计基本要求 (2)课程设计目的 (2)课程设计任务 (2)课程设计要求 (2)二、程序简介 (2)开发环境 (2)程序界面 (3)三、原理概述 (4)FTP协议 (4)应用WinSock实现网络通信 (5)四、主要数据结构 (6)五、CFTPClient类 (8)控制连接的实现 (8)数据连接的实现 (11)六、体会 (13)一、课程设计基本要求●课程设计目的1 加深对TCP/IP协议的理解。
2 了解FTP协议的工作原理。
3 掌握用MFC编写FTP协议的实现程序。
●课程设计任务在Visual C++6.0的环境下实现FTP下载工具。
●课程设计要求1 了解FTP协议的工作原理。
(RFC765 , RFC2228, RFC2640, RFC2773)2 主要是基于TCP/IP的Winsock编程,用Visual C++6.0实现一个基于FTP协议的FTP下载工具(客户端)。
二、程序简介●开发环境操作系统:Microsoft Windows XP pro编译环境:Microsoft Visual C++ 6.0CPU:PM-1.7GHz内存:768MB硬盘:40MB分辨率:32bit 1024×768 程序界面三、原理概述FTP协议FTP是Internet上基于TCP/IP协议传输文件的应用层协议。
FTP规定了数据包的格式、数据包头部结构和命令结构等等。
FTP应用命令行方式传输文件。
FTP在RFC959中定义。
FTP应用TCP传输而不是UDP。
由FTP提供的文件传输是将一个完整的文件从一个系统复制到另一个系统中。
应用FTP首先需要登录FTP服务器,或者通过允许匿名FTP来使用FTP服务器。
FTP最早的设计是用于两台不同的主机即不同的操作系统下,不同的文件结构,不同的字符集。
FTP是建立两个TCP连接(见图) ,一个用于传输数据,另一个用于传输命令。
每个FTP主机都有一个“协议解析器”( Pr ot oco1 I nter p reter, PI )模块,负责解释并执行FTP命令和响应。
同时,每个FTP主机还有一个“FTP数据传送”( FTPData Transfer,D T)模块,负责处理数据。
FTP通过执行“Telnet”(虚拟终端)模块或通过完全重新实施Telnet 作为“协议解析器”。
FTP命令以纯文本形式发送,其响应同样也是纯文本形式,并在三位数字后跟某些文本。
这些数字可由软件用来确定下面要采取的步骤。
而文本则供用户阅读。
每一个命令都会产生一个或多个响应。
应用WinSock实现网络通信WinSock是Microsoft等公司联合开发的网络编程接口,其实是一种进程间相互通信的机制,并将这种进程间通信从单机环境扩展到网络环境,适合于开发主机/客户机通信程序。
网络通信包括两台主机或者两个进程通过网络传递数据,网络的每一端称为一个端点,而WinSock为网络端点的抽象表示。
当用其编程时,程序在网络对话的每端都需要一个Socket,两个Socket之间可以应用面向连接的或者是无连接的网络协议。
面向连接的协议通过互换确认信息在连接端口之间建立一条虚电路,它不必关心网络软件传送数据。
因而面向连接的客户程序不必指定本地协议端口,而只需为Socket提供远程主机信息;IP地址和协议端口,WinSock可自动保存本地IP地址和选择本地端口。
面向连接的WinSock客户机/服务器模型,服务器在没有请求到达时,它处于等待状态。
一旦请求到来,服务器立即产生一个子进程,然后回到等待状态,由子进程相应请求。
当下一个请求到达时,服务器再产生一个新进程。
其中,并发服务器成为主服务器,子进程称为从服务器。
这种主从服务器的方式巧妙地解决了并发请求问题。
四、主要数据结构CSFTPApp类CWinApp类的派生类,由编译器自动生成,该对象代表了应用进程的主线程。
CMainFrame类CFrameWnd类的派生类,由编译器自动生成,用于创建应用程序的主窗口,它能很好地支持系统菜单和控制条(工具条、状态条等)。
在编写文档/视图结构的应用程序时,它作为主窗口管理视图和文档对象。
CSFTPDoc类CDocument类的派生类,由编译器自动生成,它只是提供了一个框架,为文档对象与相关的其他对象(视图、应用程序对象及框架窗口等)进行交互提供了框架。
对CSFTPDoc 类的设计工作,基本上都是在这个已有框架的基础上,添加所需要的功能代码。
CDFTPView类CListView类的派生类,同样由编译器自动生成,在本程序中用于显示FTP服务器上的文件列表。
CAboutDlg类CDialog类的派生类,由编译器自动生成,用于显示帮助信息。
CMessageDlg类CDialog类的派生类,用于显示从FTP服务器发来的响应信息。
CListItem类用来解析FTP服务器发送过来的文件列表信息,将每个文件的类型、名称、大小、创建时间和访问权限分别提取出来。
CFTPClient类这是实现FTP协议的主要部分,也是本文档要着重解释的一个类。
五、CFTPClient类控制连接的实现FTP客户端与服务器端建立连接的流程为1.创建一个套接字,并且与服务器建立连接。
2.创建CArchive对象、CSocketFile对象和CSocket对象之间的关联。
3.用于控制的数据流连接已经建立,可以发送命令与接收响应。
4.依次发送USER和PASS命令成功登录服务器。
MFC中提供了一个网络编程模式,可以充分利用CSocket的特性。
该模式的基础是CSocketFile类。
使用方法如下:首先,构造一个CSocket对象;调用Create函数创建一个socket对象(SOCK_STREAM类型)。
接着,如果是客户程序,调用Connect连接到远地主机;如果是服务器程序,先调用Listen监听socket端口,收到连接请求后调用Accept接收请求。
然后,创建一个和CSocket对象关联的CSocketFile对象,创建一个和CSocketFile 对象关联的CArchive对象,指定CArchive对象是用于读或者写。
如果既要读又要写,则创建两个CArchive对象。
创建工作完成之后,使用CArchive对象在客户和服务器之间传送数据。
使用完毕,销毁CArchive对象、CSocketFile对象、CSocket对象。
BOOL ConnectServer(CString serverhost,int serverport);首先创建一个套接字与服务器建立连接。
(代码如下图)然后建立CArchive对象(m_pCtrlOutarch和m_pCtrlInarch)、CSocketFile对象(m_pCtrlsokfile)和CSocket对象(m_Ctrlsok)之间的关联,用于发送和接收数据。
(代码如下图)BOOL FTPcommand(CString command);BOOL WriteStr(CString outputstring);int ReadStr();后两个方法WriteStr和ReadStr利用已经在ConnectServer()中初始化的两个CArchive对象提供的方法向服务器发送和接受数据,而FTPcommand(CString command)则是调用这两个函数实现发送命令和接收响应的功能。
(代码如下图)值得一提的是m_fc表示响应代码的第一位。
在FTP协议中,对响应代码有着详细的规定,1yz表示预备状态,2yz表示完成状态,3yz表示中间状态,4yz表示暂时拒绝状态,5yz表示永久拒绝状态。
例如:150 File status okay; about to open data connection. (文件状态OK,将打开数据连接)200 Command okay. (命令OK)331 User name okay, need password. (用户名OK,需要密码)425 Can't open data connection. (不能打开数据连接)501 Syntax error in parameters or arguments. (参数语法错误)故m_fc可用于判断操作是否成功。
BOOL Logon(CString hostname,int hostport,CString username, CString password);登录FTP服务器的函数,(主要代码如下)。
数据连接的实现BOOL DownloadFile(CString remotefile, CString localfile,BOOL get);数据传输由本函数实现流程图如下:BOOL List();本函数用于接收由数据通道发来的文件列表信息,基本流程与DownloadFile函数相同,唯一的区别是DownloadFile把数据写入文件,而List()接收数据后进行解析并显示出来。
六、体会通过本工程的实践,不论是FTP原理和算法,还是编程能力上都有很大提高。
一方面,实践了许多计算机网络介绍的算法,使得学习印象很深,收获很大,另一方面,熟悉了VC++和MFC环境编程,使自己在能力上有很大的提高。
项目完成过程中得到了助教和同学的悉心帮助,在此表示感谢。