KYSL laoyuan 发来交叉编译后的ftp仓库 源码分析 在arm摄像头下用法分析(数据服务器ip登录用户及密码)ftp(netkit-ftp)客户端的搭建(arm移植ftp)

Posted Dontla

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了KYSL laoyuan 发来交叉编译后的ftp仓库 源码分析 在arm摄像头下用法分析(数据服务器ip登录用户及密码)ftp(netkit-ftp)客户端的搭建(arm移植ftp)相关的知识,希望对你有一定的参考价值。

仓库地址:https://gitee.com/lovelydett/FTP_client?_from=gitee_search

源码分析

/* header files */
#include	<stdio.h>
#include	<stdlib.h>
#include	<netdb.h>	/* getservbyname(), gethostbyname() */
#include	<errno.h>	/* for definition of errno */
#include 	<fcntl.h>	//@tt:for file operates
#include 	<string.h>
#include 	<unistd.h>
#include 	<limits.h>
#include    <thread>
//@tt: for use of select()
#include    <sys/select.h>  
#include 	<sys/socket.h>
#include 	<sys/types.h>
#include 	<sys/stat.h>
#include 	<sys/ioctl.h>
#include	<netinet/in.h>
#include	<arpa/inet.h>

/* define macros*/
#define MAXBUF	1024
#define STDIN_FILENO	0
#define STDOUT_FILENO	1

/* define FTP reply code */
#define USERNAME	220
#define PASSWORD	331
#define LOGIN		230
#define PATHNAME	257
#define CLOSEDATA	226
#define ACTIONOK	250

enum LS,GET,PUTnextCmdMode;

/* Define global variables */
char	*host;		/* hostname or dotted-decimal string */
int		port;
char	*rbuf, *rbuf1;		/* pointer that is malloc'ed */			//read buffer
char	*wbuf, *wbuf1;		/* pointer that is malloc'ed */			//write buffer
struct sockaddr_in	servaddr;//@tt:server's socket address 
int nRet = 0;
char *fileName;

int	    cliopen(char *host, int port);
int     strtosrv(char *str, char *host);//@tt:ip stored in host and port returned
void	cmd_tcp(int sockfd);
void	ftp_list(int sockfd);
int	    ftp_get(int sck, char *pDownloadFileName_s);
int	    ftp_put (int sck, char *pUploadFileName_s);

int main(int argc, char *argv[])

	int	fd;
	nRet = socket(AF_INET,SOCK_STREAM,0);
    //@tt: to check if cmd includes ip
	if (0 != argc-2)	//意思就是只能输入一个host ip参数
	
		printf("%s\\n","missing <hostname>");
		exit(0);
	

	host = argv[1];	//主机名?
	port = 21;

	
	//1. code here: Allocate the read and write buffers before open().
    //@tt: allocate buffer for rbuf, wbuf... etc
	rbuf = (char*)malloc(MAXBUF);
	wbuf = (char*)malloc(MAXBUF);
	rbuf1 = (char*)malloc(MAXBUF);
	wbuf1 = (char*)malloc(MAXBUF);
	fileName = (char*)malloc(MAXBUF);

	fd = cliopen(host, port);
	if(-1==fd)return -1;

	cmd_tcp(fd);
	free(rbuf);
	free(rbuf1);
	free(wbuf);
	free(wbuf1);
	free(fileName);

	exit(0);



//@tt: establish a tcp connection at host:port
int cliopen(char *host, int port)

    printf("\\n----------tcp connection establishing---------- \\n");
    int socketCmd;
	if( -1==(socketCmd = socket(AF_INET,SOCK_STREAM,0)))//@tt: open socket for cmd and get socketID
    
        printf("error: enable to open socket at: cliopen\\n");
        return -1;
    


    struct hostent *ht = NULL;//@tt: used for acquire servaddr
	char hostname[128];
	hostname[127] = 0;
    // if (gethostname(hostname, 128) == 0)
    //     puts(hostname);
    // else
    //     perror("gethostname");
	// ht = gethostbyname(host);
    // if(NULL == ht)
    // 
    //     printf("error: enable to get host by name: %s at: cliopen\\n",host);
    //     return -1;
    // 
    memset(&servaddr,0,sizeof(struct sockaddr_in));//@tt: clear servaddr
    
	//memcpy(&servaddr.sin_addr.s_addr,(in_addr_t*)ht->h_addr_list,ht->h_length);//@tt: get serveraddr
	//memcpy(&servaddr.sin_addr.s_addr,(in_addr_t*)ht->h_addr_list,ht->h_length);//@tt: get serveraddr
    
	servaddr.sin_addr.s_addr = inet_addr(host);
	servaddr.sin_port = htons(port);//@tt:transfer to big-endian
	servaddr.sin_family = AF_INET;
	printf("connecting to server:%s\\n",host);
	
	nRet = connect(socketCmd,(struct sockaddr*)&servaddr,sizeof(servaddr));//@tt:force to transfer to sockaddr*
	if(0!=nRet)
	
		printf("error in tcp connection: nRet = %d \\n",nRet);
		return -1;
	
	printf("----------tcp connection established---------- \\n");
	return socketCmd;



/*
   Compute server's port by a pair of integers and store it in char *port	//获取服务器端口并存在*port里
   Get server's IP address and store it in char *host	//获取服务器ip并存在*host里
*/
int    strtosrv(char *str, char *host)

	unsigned int serverAdd[6];
	int temp_int;
	char temp_str[128];
	char temp;
	sscanf(str,"%d %s %s %s %c%d,%d,%d,%d,%d,%d%c",&temp_int,temp_str,temp_str,temp_str,&temp,&serverAdd[0],&serverAdd[1],&serverAdd[2],&serverAdd[3],&serverAdd[4],&serverAdd[5],&temp);  
	memset(host,0,strlen(host));
	sprintf(host,"%d.%d.%d.%d",serverAdd[0],serverAdd[1],serverAdd[2],serverAdd[3]);
	return serverAdd[4]*256 + serverAdd[5];



/* Read and write as command connection */
void cmd_tcp(int sockfd)

	int		maxfdp1, nread, nwrite, fd, replycode;
	char	host[16];
	int		port;
	fd_set	rset;

	FD_ZERO(&rset);
	maxfdp1 = sockfd + 1;	/* check descriptors [0..sockfd] */

	while(1)
	
		FD_SET(STDIN_FILENO, &rset);//@tt:stdin
		FD_SET(sockfd, &rset);//@tt:socketCmd

		nRet = select(maxfdp1, &rset, NULL, NULL, NULL);//@tt:check if rset(s) readable	//socket里的非阻塞监听事件是否发生(本质还是循环监听)
		if (0>=nRet)
		
			printf("error: select error, nRet:%d\\n",nRet);
		
		/* data to read on stdin */
		if (FD_ISSET(STDIN_FILENO, &rset)) //@tt:if data readable in stdin
		
			memset(rbuf,'\\0',MAXBUF);
			memset(wbuf,'\\0',MAXBUF);
			memset(wbuf1,'\\0',MAXBUF);
			if ( (nread = read(STDIN_FILENO, rbuf, MAXBUF)) < 0)
				printf("read error from stdin\\n");
			nwrite = nread+5;

			/* send username */
			if (replycode == USERNAME) //@tt:read username from stdin and send to serverCMD
			
				sprintf(wbuf, "USER %s", rbuf);
				if (write(sockfd, wbuf, nwrite) != nwrite)
					printf("write error\\n");
			

			if(replycode == PASSWORD) //@tt: read password from stdin and send to server
			 /*************************************************************
			 //4. code here: send password
			 *************************************************************/
			
				sprintf(wbuf, "PASS %s", rbuf);
				if (write(sockfd, wbuf, nwrite) != nwrite)
					printf("write error\\n");
			

			 /* send command */
			if (replycode==LOGIN || replycode==CLOSEDATA || replycode==PATHNAME || replycode==ACTIONOK)
			
				/* ls - list files and directories*/
				if (strncmp(rbuf, "ls", 2) == 0) 
				
					sprintf(wbuf, "%s", "PASV\\n");
					write(sockfd, wbuf, 5);//@tt:send to server's cmdSock: PASV
					sprintf(wbuf1, "%s", "LIST -al\\n");
					nextCmdMode = LS;
					continue;
				

				/*************************************************************
				// 5. code here: cd - change working directory/
				*************************************************************/
				if (strncmp(rbuf, "cd", 2) == 0) 
				
					memset(fileName,'\\0',strlen(fileName));
					sscanf(rbuf,"cd %s",fileName);
					sprintf(wbuf, "CWD %s", fileName);	//这就相当于将我们输入的指令转发给服务器终端了
					write(sockfd, wbuf, nread);//@tt:send to server's cmdSock: CWD xxxxxx...
					continue;
				

				/* pwd -  print working directory */
				if (strncmp(rbuf, "pwd", 3) == 0) 
				
					sprintf(wbuf, "%s", "PWD\\n");
					write(sockfd, wbuf, 4);
					continue;
				

				/*************************************************************
				// 6. code here: quit - quit from ftp server
				*************************************************************/
				if (strncmp(rbuf, "quit", 4) == 0) 
				
					sprintf(wbuf, "%s", "QUIT\\n");
					write(sockfd, wbuf, 5);
					nRet = close(sockfd);
					if(nRet<0)
					
						printf("error: failed to close sock:%d\\n",sockfd);
					
					break;
				


				/*************************************************************
				// 7. code here: get - get file from ftp server
				*************************************************************/
				if (strncmp(rbuf, "get", 3) == 0) 
				
					sprintf(wbuf, "%s", "PASV\\n");
					memset(fileName,'\\0',strlen(fileName));
					sscanf(rbuf,"get %s",fileName);
					sprintf(wbuf1, "RETR %s", fileName);
					write(sockfd,wbuf,5);//@tt:get connected in PASV mode
					nextCmdMode = GET;
					continue;
				

				/*************************************************************
				// 8. code here: put -  put file upto ftp server
				*************************************************************/
				if (strncmp(rbuf, "put", 3) == 0) 
				
					sprintf(wbuf, "%s", "PASV\\n");
					memset(fileName,'\\0',strlen(fileName));	//有1024个字节
					sscanf(rbuf,"put %s",fileName);
					sprintf(wbuf1, "STOR %s", fileName);//@tt:set next cmd line
					write(sockfd,wbuf,5);//@tt:get connected in PASV mode
					nextCmdMode = PUT;
					continue;
				

				else
				
					printf("\\n error: wrong cmd line. \\n");
					continue;
				
				

			
		

		/* data to read from socket */
		if (FD_ISSET(sockfd, &rset)) 
			if ( (nread = recv(sockfd, rbuf, MAXBUF, 0)) < 0)
			
				printf("recv error\\n");
				continue;
			
			else if (nread == 0)
				continue;
			write(STDOUT_FILENO, rbuf, strlen(rbuf));
			/* set replycode and wait for user's input */
			if (strncmp(rbuf, "220", 3)==0 || strncmp(rbuf, "530", 3)==0)
				write(STDOUT_FILENO,"your name: ",strlen("your name: "));
				//nread += 12;
				replycode = USERNAME;
			

			/*************************************************************
			// 9. code here: handle other response coming from server
			*************************************************************/

			/* open data connection*/
			if (strncmp(rbuf, "227", 3) == 0) 
				//printf("A: %s\\n",rbuf);
				port = strtosrv(rbuf, host);
				fd = cliopen(host, port);
				switch (nextCmdMode)
				
				case LS:
					if(write(sockfd, wbuf1, strlen(wbuf1))!=strlen(wbuf1))
					
						printf("error: failed to send cmd to serversock");
					
					ftp_list(fd);
					break;
				case GET:
				
					if(write(sockfd, wbuf1, strlen(wbuf1))!=strlen(wbuf1))
					
						printf("error: failed to send cmd to serversock");
					
					std::thread *t = new std::thread(ftp_get,fd,fileName);
					t->detach();
					break;
				
				case PUT:
				
					if(write(sockfd, wbuf1, strlen(wbuf1))!=strlen(wbuf1))
					
						printf("error: failed to send cmd to serversock");
					
					std::thread *t = new std::thread(ftp_put,fd,fileName);
					t->detach();
					break;	
							
				default:
					break;
				
				nwrite = 0;
			
			if(strncmp(rbuf,"331",3) == 0)
			
				write(STDOUT_FILENO,"your password:",strlen("your password:"));
				nread += 16;
 				replycode = PASSWORD;
			
			if(strncmp(rbuf,"230",3) == 0)
			
 				replycode = LOGIN;
			
			if(strncmp(rbuf,"257",3) == 0)
			
 				replycode = PATHNAME;
			
			if(strncmp(rbuf,"250",3) == 0)
			
 				replycode = ACTIONOK;
			
			if(strncmp(rbuf,"226",3) == 0)
			
 				replycode = CLOSEDATA;
			
			/* start data transfer */

		
	

	
	if (close(sockfd) < 0)
		printf("close error\\n");



/* Read and write as data transfer connection */
void ftp_list(int sockfd)

	int		nread;

	for ( ; ; )
	<

以上是关于KYSL laoyuan 发来交叉编译后的ftp仓库 源码分析 在arm摄像头下用法分析(数据服务器ip登录用户及密码)ftp(netkit-ftp)客户端的搭建(arm移植ftp)的主要内容,如果未能解决你的问题,请参考以下文章

如何在Ubuntu下建立交叉编译环境

如何在ubuntu中搭建交叉编译环境toolchain

交叉编译inetutils并配置telnet服务

KYSL 海康摄像头 8247 h9 isapi测试(libopdevsdk.so)

KYSL 海康摄像头 8247 h9 isapi测试(libopdevsdk.so)

Golang 交叉编译