栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

Vxworks FTP移植到Sylixos使用笔记

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Vxworks FTP移植到Sylixos使用笔记

类别内容
关键词Sylixos FTP Vxworks
摘 要Vxworks组件FTP移植和使用

目录
  • 1. 适用范围
  • 2. 原理概述
    • 2.1 FTP原理
  • 3. 准备工作
  • 3.1 环境准备
    • 3.2 资源准备
  • 4. 技术实现
    • 4.1 base工程和app工程设置
    • 4.2 ftpLib移植
  • 5. 如何使用FTP
  • 6. 总结

1. 适用范围

本文适用对FTP有使用需求的工程师,讲述从FTP移植到使用。

2. 原理概述

文件传输协议(File Transfer Protocol,FTP)是用于在网络上进行文件传输的一套标准协议,它工作在 OSI 模型的第七层, TCP 模型的第四层, 即应用层, 使用 TCP 传输而不是 UDP, 客户在和服务器建立连接前要经过一个“三次握手”的过程, 保证客户与服务器之间的连接是可靠的, 而且是面向连接, 为数据传输提供可靠保证。
FTP允许用户以文件操作的方式(如文件的增、删、改、查、传送等)与另一主机相互通信。然而, 用户并不真正登录到自己想要存取的计算机上面而成为完全用户, 可用FTP程序访问远程资源, 实现用户往返传输文件、目录管理以及访问电子邮件等等, 即使双方计算机可能配有不同的操作系统和文件存储方式。

2.1 FTP原理

FTP主要用来进行文件传输,包括命令信道和数据信道,命令信道用来交互命令控制,数据信道用来传输文件数据。
首先客户端需要进行登录FTP服务器,TCP建立连接,通过命令信道发送登录命令,传输数据时,通过命令信道交互数据端口号,彼此建立数据连接,数据可通过数据连接进行传输。
文件传输可选文件类型:ASCII码文件(默认的)/ 图像文件类型(二进制的)/ 本地文件类型(用于在具有不同字节大小主机间传送二进制数据)
与服务器连接分为两种模式:
主动 FTP :
    命令连接:客户端 >1024 端口 → 服务器 21 端口
    数据连接:客户端 >1024 端口 ← 服务器 20 端口
被动 FTP :
    命令连接:客户端 >1024 端口 → 服务器 21 端口
    数据连接:客户端 >1024 端口 ← 服务器 >1024 端口
  PORT(主动)方式的连接过程是:客户端向服务器的FTP端口(默认是21)发送连接请求,服务器接受连接,建立一条命令链路。 当需要传送数据时, 客户端在命令链路上用PORT命令告诉服务器:“我打开了***X端口,你过来连接我”。于是服务器从20端口向客户端的***X端口发送连接请求,建立 一条数据链路来传送数据。
  PASV(被动)方式的连接过程是:客户端向服务器的FTP端口(默认是21)发送连接请求,服务器接受连接,建立一条命令链路。 当需要传送数据时, 服务器在命令链路上用PASV命令告诉客户端:“我打开了***X端口,你过来连接我”。于是客户端向服务器的***X端口发送连接请求,建立一条数据链 路来传送数据。
早先所有客户端都使用主动模式,而且工作的很好,而现在因为客户端防火墙的存在,将会关闭一些端口,这样主动模式将会失败。在这种情况下就要使用被动模式,但是一些端口也可能被服务器的防火墙封掉。不过因为ftp服务器需要它的ftp服务连接到一定数量的客户端,所以他们总是支持被动模式的。这就是我们为什么要使用被动模式的原意,为了确保数据可以正确的传输,使用被动模式要明显优于主动模式。(译者注:主动(PORT)模式建立数据传输通道是由服务器端发起的,服务器使用20端口连接客户端的某一个大于1024的 端口;在被动(PASV)模式中,数据传输的通道的建立是由FTP客户端发起的,他使用一个大于1024的端口连接服务器的1024以上的某一个端口)
主动模式传送数据时是“服务器”连接到“客户端”的端口;
被动模式传送数据是“客户端”连接到“服务器”的端口。
主动模式需要客户端必须开放端口给服务器,很多客户端都是在防火墙内,开放端口给FTP服务器访问比较困难。
被动模式只需要服务器端开放端口给客户端连接就行了。
FTP服务器一般都支持主动和被动模式,连接采用何种模式是有FTP客户端软件决定。
FTP被动模式的出现原因
在FTP的历史中,本来只有主动模式的,但是为什么又出现了被动模式呢?这又牵涉到另外一个问题了。
在很久以前(我也不知道多久),地球上还没有什么共享上网这种技术,但是后来出现了,所以也就有了下面的问题,大家都知道,共享上网就是很 多台电脑共享一个公网IP去使用internet,再打个比喻吧,某个局域网共享210.33.25.1这个公网IP上网,当一个内网用户 192.168.0.100去访问外网的FTP服务器时,如果采用主动模式的话,192.168.0.1告诉了FTP服务器我需要某个文件和我打开了x端 口之后,由于共享上网的原因,192.168.0.1在出网关的时候自己的IP地址已经被翻译成了210.33.25.1这个公网IP,所以服务器端收到 的消息也就是210.33.25.1需要某个文件并打开了x端口,FTP服务器就会往210.33.25.1的x端口传数据,这样当然会连接不成功了,因为打开x端口的并不是210.33.25.1这个地址,在这种情况下被动模式就有用了,相信大家已经能够理解被动模式是怎么个连接法了吧。
  在主动模式中,FTP的两个端口是相对固定的,如果命令端口是x的话,那数据端口就是x-1,也就是说默认情况下,命令端口是21,数据端口就是20;你把命令端口改成了123,那么数据端口就是122。这样使用防火墙就很方便了,只要开通这两个端口就可以了,但是如果客户端是共享上网的话那岂不是不能正常使用FTP了,这样还是不行,一定需要被动模式。
  在被动模式中就麻烦了些,默认情况下命令端口是21,但是数据端口是随机的
因此推荐使用被动模式。

3. 准备工作 3.1 环境准备
  • FTP服务器关闭防火墙
  • FTP服务器开启FTP
3.2 资源准备
  • Vxworks源码(包括组件ftpLib.c)
  • Sylixos的工程文件
4. 技术实现 4.1 base工程和app工程设置

base工程选中libVxWorks,app工程进行连接so动态库。


4.2 ftpLib移植

FTP实现依赖TCP进行通信,均使用POSIX标准接口,几乎不需要修改,主要针对警告以及缺失函数部分。

#ifndef SYLIXOS
#include 
#endif
#include 
#ifndef SYLIXOS
#include 
#include 
#else
#include "ftpLib.h"
#include "taskLibCommon.h"
#include 

#define log_err(__LOG_LEVEL, ...)      
    do{
    if((__LOG_LEVEL) & 1)
    {
        if((__LOG_LEVEL) & LOG_ERRNO)
        {
            printf("error #");
        }
    printf(__VA_ARGS__);printf("rn");
    }
}while(0);
#define log_info      log_err
#define log_warning   log_err

#endif

STATUS logLevelChange
    (
    int category,    
    UINT mask        
    )
    {

    return OK;
    }

#ifndef SYLIXOS
            log_err (FTP_LOG, "Timeout %lu sec.", replyTimeOut.tv_sec);
#else
            log_err (FTP_LOG, "Timeout %lu sec.", (ULONG)replyTimeOut.tv_sec);
#endif

#ifndef SYLIXOS
    int len;
#else
    UINT len;
#endif

#ifndef SYLIXOS
        bzero ((char *) &dataAddr, sizeof (SOCKADDR));
#else
        bzero ((char *) &dataAddr, sizeof (SOCKADDR_IN));
#endif

#ifndef SYLIXOS
    int len;
#else
    UINT len;
#endif

#ifndef SYLIXOS
    int fromlen = sizeof (from);
#else
    UINT fromlen = sizeof (from);
#endif

#ifndef SYLIXOS
             log_err (FTP_LOG, "select timeout after %lu sec.", replyTime.tv_sec);
#else
             log_err (FTP_LOG, "select timeout after %lu sec.", (ULONG)replyTime.tv_sec);
#endif

c文件需要将警告部分优化,以及确实函数的实现,h文件主要缺失一些宏定义,进行补全移植全部完成。

#ifndef SYLIXOS
#include 
#include 
#endif

#ifdef SYLIXOS
#include 

#define MAX_IDENTITY_LEN              100
#define MIN_RESV_PORT                 600
#define MAX_RESV_PORT                 1023

#ifndef MAXHOSTNAMELEN
#define MAXHOSTNAMELEN                64
#endif

#define FTP_LOG                       1

#define LOG_ERRNO                     0x10 

#undef  FTP_TRANSIENT_MAX_RETRY_COUNT
#define FTP_TRANSIENT_MAX_RETRY_COUNT 100
#undef  FTP_TRANSIENT_RETRY_INTERVAL
#define FTP_TRANSIENT_RETRY_INTERVAL  0
#undef  FTP_DEBUG_OPTIONS
#define FTP_DEBUG_OPTIONS             0
#undef  FTP_TIMEOUT
#define FTP_TIMEOUT                   0

extern UINT32  ftplTransientMaxRetryCount;   
extern UINT32  ftplTransientRetryInterval;   
#endif

5. 如何使用FTP

一般应用都需要进行初始化才能使用,初始化是可以省略的,只是针对一些时间的设置等。


LOCAL BOOL ftpTransientFatal
    (
    UINT32 reply 
    )
    {
    switch (reply)
        {
        case (421): 
        case (450): 
        case (451): 
        case (452): 
            {
            
            return (TRUE);
            }
            
        default:
        return (FALSE);
        }
    }

#define FTP_TRANSIENT_FATAL ftpTransientFatal


STATUS usrFtpInit (void)
    {
    ftpLibInit (FTP_TIMEOUT);
    ftplTransientMaxRetryCount = FTP_TRANSIENT_MAX_RETRY_COUNT; 
    ftplTransientRetryInterval = FTP_TRANSIENT_RETRY_INTERVAL; 
    ftpTransientFatalInstall ( FTP_TRANSIENT_FATAL ); 
    ftpLibDebugOptionsSet ( FTP_DEBUG_OPTIONS );    

    return OK;
    }

FTP使用主要使用ftpXfer函数进行文件的上传和下载。ftpXfer函数内部的函数也可单独使用,如果有需求可参照ftpXfer函数自己定制。

STATUS ftpXfer
    (
    char *host,         
    char *user,         
    char *passwd,       
    char *acct,         
    char *cmd,          
    char *dirname,      
    char *filename,     
    int *pCtrlSock,     
    int *pDataSock      
                        
    )

文件上传和下载例子。

#include 
#include "ftpLib.h"
#include "socket.h"

#define HOST          "192.168.1.10"
#define USER          "anonymous"                                      
#define PWD           " "                                              
#define W_DIR         "/ftptest"                                       


#define RD_CMD        "RETR %s"
#define WR_CMD        "STOR %s"                                        
#define FILE          "fromserver.txt"
#define TOSERVER_FILE "toserver.txt"


void FtpDownload()
{
 int ctrlSock;
 int dataSock;
 char buf[512];
 int nBytes;

 if(ERROR == ftpXfer(HOST, USER, PWD, "", RD_CMD, W_DIR, FILE, &ctrlSock, &dataSock))
 {
  printf("rn ftp connected failed!");
  return ;
 }

 while((nBytes = read(dataSock, buf, sizeof(buf))) > 0)
 {
  printf("rn it is [%s]", buf);
 }

 close(dataSock);

 if(ERROR == nBytes)
  printf("rnit is reading error.");

 if(ftpCommand(ctrlSock, "QUIT", 0, 0, 0, 0, 0, 0) == FTP_COMPLETE)
  printf("rnftp is completed");
 close(ctrlSock);
}


void FtpUpload ()
{
    int ctrlSock;
    int dataSock;
    int nBytes;

#define FTP_WRITE_TIMEOUT_DEFAULT 30

    struct timeval tm;
    tm.tv_sec = FTP_WRITE_TIMEOUT_DEFAULT;
    tm.tv_usec = 0;

    if(ERROR == ftpXfer(HOST, USER, PWD, "", WR_CMD, W_DIR, TOSERVER_FILE, &ctrlSock, &dataSock))
    {
     printf("rn ftp connected failed!");
     return ;
    }

    setsockopt(dataSock,SOL_SOCKET,SO_SNDTIMEO,(char*)&tm,sizeof(struct timeval));

    const PCHAR const ptr = "This is a test!.";

    nBytes = write (dataSock, ptr, strlen(ptr));

    close(dataSock);

    if(ERROR == nBytes)
        printf("rnit is reading error.");

    if(ftpCommand(ctrlSock, "QUIT", 0, 0, 0, 0, 0, 0) == FTP_COMPLETE)
        printf("rnftp is completed");
    close(ctrlSock);
}

可以看到使用了两个信道,命令信道和数据信道。
命令
控制信道进行命令的传输,简要列举了一些控制命令。

6. 总结

大概了解FTP原理即可,ftpLib已经实现了FTP功能,知道两个信道,使用时就得心应手了。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/312772.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号