第 2 章 - FTP 的安装和使用

本章介绍了与安装、设置和使用 NetX Duo FTP 服务相关的各种问题。

产品分发

NetX Duo FTP 在 https://github.com/azure-rtos/netxduo 上提供。 该程序包包含两个源文件和一个 PDF 文件(其中包含本文档),如下所示:

  • nxd_ftp_client.h:NetX Duo FTP 客户端的头文件
  • nxd_ftp_client.c:NetX Duo FTP 客户端的 C 源文件
  • nxd_ftp_server.h:NetX Duo FTP 服务器的头文件
  • nxd_ftp_server.c:NetX Duo FTP 服务器的 C 源文件
  • filex_stub.h:存根文件(如果 FileX 不存在)
  • nxd_ftp.pdf:NetX Duo FTP 的 PDF 说明
  • demo_netxduo_ftp.c:FTP 演示系统

NetX Duo FTP 安装

若要使用 NetX Duo FTP API,应将前面提到的整个分发包复制到 NetX Duo 所安装在的目录中。 例如,如果 NetX Duo 安装到了目录“\threadx\arm7\green”中,则应将 nxd_ftp_client.h 和 nxd_ftp_client.c 复制到 FTP 客户端应用程序的此目录中,将 nxd_ftp_server.h 和 nxd_ftp_server.c 文件复制到 FTP 服务器应用程序的此目录中。

使用 NetX Duo FTP

使用 NetX Duo FTP API 很容易。 基本上来说,应用程序代码必须包括 nxd_ftp_client.h(适用于 FTP 客户端应用程序)或 nxd_ftp_server(适用于 FTP 服务器应用程序)。之后,为了分别使用 ThreadX、FileX 和 NetX Duo,还需要包括 tx_api.h、fx_api.h 和 nx_api.h。 生成项目必须包括 FTP 源代码和主机应用程序文件,当然还必须包括 ThreadX 库文件和 NetX 库文件。 这就是使用 NetX Duo FTP 所需的一切。

请注意,由于 FTP 采用 NetX Duo TCP 服务,因此在使用 FTP 之前,必须通过 nx_tcp_enable 调用来启用 TCP。

请注意,可以为 NetX Duo 库启用 IPv6,同时仍让其支持 IPv4 网络。 但是,除非为 NetX Duo 启用 IPv6,否则 NetX Duo 不能支持 IPv6。 若要在 NetX Duo 中禁用 IPv6 处理,必须在 nx_user.h 文件中定义 NX_DISABLE_IPV6,并且必须通过在 nx_port.h 文件中定义 NX_INCLUDE_USER_DEFINE_FILE 将该文件包括在 NetX Duo 库生成中。 默认情况下,NX_DISABLE_IPV6 未定义(IPv6 已启用)。 这不同于 nxd_ipv6_enable 服务,该服务在 IP 任务中设置 IPv6 协议和服务,并且要求不定义 NX_DISABLE_IPV6。

NetX Duo FTP 的小型示例系统

下面的图 1.1 举例说明了 NetX Duo FTP 是多么易于使用。 在此示例中,同时创建了 FTP 服务器和 FTP 客户端。 因此,第 10 行和第 11 行中引入了 FTP include 文件 nxd_ftp_client.h 和 nxd_ftp_server.h。 接下来,在第 99 行的“tx_application_define”中创建了 FTP 服务器。 请注意,FTP 服务器和客户端控制块以前在第 26 行中定义为全局变量。

此演示介绍了如何使用 NetX Duo FTP 中提供的 duo 函数以及仅限 IPv4 的旧 FTP 服务。 为了使用 IPv6 函数,此演示在第 16 行中定义了 USE_IPV6

如果主机应用程序定义了同时支持 IPv4 和 IPv6 的 USE_IPV6,则在第 162 行通过 nxd_ftp_server_create 创建 FTP 服务器。 否则会在第 166 行通过 nx_ftp_server_create 创建可与仅限 IPv4 的服务配合使用的 FTP 服务器。 请注意,“duo”函数使用不同于 IPv4 服务的登录和注销函数参数,这两个参数在文件底部的第 534 -568 行定义。

然后,FTP 服务器必须通过 NetX Duo 建立其 IPv6 地址(全局和链路本地),从第 466 行中的 FTP 服务器线程入口函数开始。 然后,FTP 服务器在第 518 行启动,做好处理 FTP 客户端请求的准备。

FTP 客户端在第 316 行中创建,将通过与 FTP 服务器相同的过程来启用 FTP 客户端 IP 任务 IPv6,并从第 263-313 行开始验证其 IPv6 地址。

然后,在第 334 行中(如果已定义了 USE_IPV6)或者在第 340 行中(如果使用仅限 IPv4 的服务 nx_ftp_client_connect),客户端使用 nxd_ftp_client_connect 连接到 FTP 服务器。 在 FTP 客户端线程函数执行过程中,它会将文件写入到 FTP 服务器并在断开连接前将其读回。

/* This is a small demo of NetX FTP on the high-performance NetX TCP/IP stack.  This demo
   relies on ThreadX, NetX, and FileX to show a simple file transfer from the client
   and then back to the server.  */



#include    "tx_api.h"
#include    "fx_api.h"
#include    "nx_api.h"
#include    "nxd_ftp_client.h"
#include    "nxd_ftp_server.h"

#define     DEMO_STACK_SIZE         4096

#ifdef FEATURE_NX_IPV6
#define USE_IPV6
#endif /* FEATURE_NX_IPV6 */


/* Define the ThreadX, NetX, and FileX object control blocks...  */

TX_THREAD               server_thread;
TX_THREAD               client_thread;
NX_PACKET_POOL          server_pool;
NX_IP                   server_ip;
NX_PACKET_POOL          client_pool;
NX_IP                   client_ip;
FX_MEDIA                ram_disk;


/* Define the NetX FTP object control blocks.  */

NX_FTP_CLIENT           ftp_client;
NX_FTP_SERVER           ftp_server;


/* Define the counters used in the demo application...  */

ULONG                   error_counter = 0;


/* Define the memory area for the FileX RAM disk.  */

UCHAR                   ram_disk_memory[32000];
UCHAR                   ram_disk_sector_cache[512];


#define FTP_SERVER_ADDRESS  IP_ADDRESS(1,2,3,4)
#define FTP_CLIENT_ADDRESS  IP_ADDRESS(1,2,3,5)

extern UINT  _fx_media_format(FX_MEDIA *media_ptr, VOID (*driver)(FX_MEDIA *media),
                        VOID *driver_info_ptr, UCHAR *memory_ptr, UINT memory_size,
                        CHAR *volume_name, UINT number_of_fats, UINT directory_entries,
                        UINT hidden_sectors, ULONG total_sectors, UINT bytes_per_sector,
                        UINT sectors_per_cluster, UINT heads, UINT sectors_per_track);

/* Define the FileX and NetX driver entry functions.  */
VOID    _fx_ram_driver(FX_MEDIA *media_ptr);

/* Replace the 'ram' driver with your own Ethernet driver. */
VOID    _nx_ram_network_driver(NX_IP_DRIVER *driver_req_ptr);


void    client_thread_entry(ULONG thread_input);
void    thread_server_entry(ULONG thread_input);


#ifdef USE_IPV6
/* Define NetX Duo IP address for the NetX Duo FTP Server and Client. */
NXD_ADDRESS     server_ip_address;
NXD_ADDRESS     client_ip_address;
endif


/* Define server login/logout functions.  These are stubs for functions that would
   validate a client login request.   */

#ifdef USE_IPV6
UINT    server_login6(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, NXD_ADDRESS *client_ipduo_address,
    UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info);
UINT    server_logout6(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, NXD_ADDRESS *client_ipduo_address,
    UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info);
#else
UINT    server_login(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr,
    ULONG client_ip_address, UINT client_port,
    CHAR *name, CHAR *password, CHAR *extra_info);
UINT    server_logout(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr,
    ULONG client_ip_address, UINT client_port,
    CHAR *name, CHAR *password, CHAR *extra_info);
#endif


/* Define main entry point.  */

int main()
{

    /* Enter the ThreadX kernel.  */
    tx_kernel_enter();
    return(0);
}


/* Define what the initial system looks like.  */

void    tx_application_define(void *first_unused_memory)
{

    UINT    status;
    UCHAR   *pointer;


    /* Setup the working pointer.  */
    pointer =  (UCHAR *) first_unused_memory;

    /* Create a helper thread for the server. */
    tx_thread_create(&server_thread, "FTP Server thread", thread_server_entry, 0,
                     pointer, DEMO_STACK_SIZE,
                     4, 4, TX_NO_TIME_SLICE, TX_AUTO_START);

    pointer =  pointer + DEMO_STACK_SIZE;

    /* Initialize NetX.  */
    nx_system_initialize();

    /* Create the packet pool for the FTP Server.  */
    status = nx_packet_pool_create(&server_pool, "NetX Server Packet Pool", 256, pointer, 8192);
    pointer = pointer + 8192;

    /* Check for errors.  */
    if (status)
        error_counter++;

    /* Create the IP instance for the FTP Server.  */
    status = nx_ip_create(&server_ip, "NetX Server IP Instance", FTP_SERVER_ADDRESS, 0xFFFFFF00UL,
                                        &server_pool, _nx_ram_network_driver, pointer, 2048, 1);
    pointer = pointer + 2048;

    /* Check status.  */
    if (status != NX_SUCCESS)
    {
        error_counter++;
        return;
    }

    /* Enable ARP and supply ARP cache memory for server IP instance.  */
    nx_arp_enable(&server_ip, (void *) pointer, 1024);
    pointer = pointer + 1024;

    /* Enable TCP.  */
    nx_tcp_enable(&server_ip);

#ifdef USE_IPV6

    /* Next set the NetX Duo FTP Server and Client addresses. */
    server_ip_address.nxd_ip_address.v6[3] = 0x105;
    server_ip_address.nxd_ip_address.v6[2] = 0x0;
    server_ip_address.nxd_ip_address.v6[1] = 0x0000f101;
    server_ip_address.nxd_ip_address.v6[0] = 0x20010db8;
    server_ip_address.nxd_ip_version = NX_IP_VERSION_V6;

    client_ip_address.nxd_ip_address.v6[3] = 0x101;
    client_ip_address.nxd_ip_address.v6[2] = 0x0;
    client_ip_address.nxd_ip_address.v6[1] = 0x0000f101;
    client_ip_address.nxd_ip_address.v6[0] = 0x20010db8;
    client_ip_address.nxd_ip_version = NX_IP_VERSION_V6;

    /* Create the FTP server.  */
    status =  nxd_ftp_server_create(&ftp_server, "FTP Server Instance", &server_ip,
                                    &ram_disk, pointer, DEMO_STACK_SIZE, &server_pool,
                                    server_login6, server_logout6);
#else
    /* Create the FTP server.  */
    status =  nx_ftp_server_create(&ftp_server, "FTP Server Instance", &server_ip,
                                    &ram_disk, pointer, DEMO_STACK_SIZE, &server_pool,
                                    server_login, server_logout);
#endif
    pointer =  pointer + DEMO_STACK_SIZE;

    /* Check status.  */
    if (status != NX_SUCCESS)
    {
        error_counter++;
        return;
    }

    /* Now set up the FTP Client. */

    /* Create the main FTP client thread.  */
    status = tx_thread_create(&client_thread, "FTP Client thread ", client_thread_entry, 0,
            pointer, DEMO_STACK_SIZE,
            6, 6, TX_NO_TIME_SLICE, TX_AUTO_START);
    pointer = pointer + DEMO_STACK_SIZE ;

    /* Check status.  */
    if (status != NX_SUCCESS)
    {
        error_counter++;
        return;
    }

    /* Create a packet pool for the FTP client.  */
    status =  nx_packet_pool_create(&client_pool, "NetX Client Packet Pool", 256, pointer, 8192);
    pointer =  pointer + 8192;

    /* Create an IP instance for the FTP client.  */
    status = nx_ip_create(&client_ip, "NetX Client IP Instance", FTP_CLIENT_ADDRESS, 0xFFFFFF00UL,
                                                &client_pool, _nx_ram_network_driver, pointer, 2048, 1);
    pointer = pointer + 2048;

    /* Enable ARP and supply ARP cache memory for the FTP Client IP.  */
    nx_arp_enable(&client_ip, (void *) pointer, 1024);

    pointer = pointer + 1024;

    /* Enable TCP for client IP instance.  */
    nx_tcp_enable(&client_ip);

    return;

}

/* Define the FTP client thread.  */

void    client_thread_entry(ULONG thread_input)
{

NX_PACKET   *my_packet;
UINT        status;

#ifdef USE_IPV6
UINT        iface_index, address_index;
#endif


    /* Format the RAM disk - the memory for the RAM disk was defined above.  */
    status = _fx_media_format(&ram_disk,
                            _fx_ram_driver,                  /* Driver entry                */
                            ram_disk_memory,                 /* RAM disk memory pointer     */
                            ram_disk_sector_cache,           /* Media buffer pointer        */
                            sizeof(ram_disk_sector_cache),   /* Media buffer size           */
                            "MY_RAM_DISK",                   /* Volume Name                 */
                            1,                               /* Number of FATs              */
                            32,                              /* Directory Entries           */
                            0,                               /* Hidden sectors              */
                            256,                             /* Total sectors               */
                            128,                             /* Sector size                 */
                            1,                               /* Sectors per cluster         */
                            1,                               /* Heads                       */
                            1);                              /* Sectors per track           */

    /* Check status.  */
    if (status != NX_SUCCESS)
    {
        error_counter++;
        return;
    }

    /* Open the RAM disk.  */
    status = fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory,
        ram_disk_sector_cache, sizeof(ram_disk_sector_cache));

    /* Check status.  */
    if (status != NX_SUCCESS)
    {
        error_counter++;
        return;
    }

    /* Let the IP threads and driver initialize the system.    */
    tx_thread_sleep(100);

#ifdef USE_IPV6

    /* Here's where we make the FTP Client IPv6 enabled. */
    status = nxd_ipv6_enable(&client_ip);

    /* Check status.  */
    if (status != NX_SUCCESS)
    {
        error_counter++;
        return;
    }

    status = nxd_icmp_enable(&client_ip);

    /* Check status.  */
    if (status != NX_SUCCESS)
    {
        error_counter++;
        return;
    }

    /* Set the Client link local and global addresses. */
    iface_index = 0;

    /* This assumes we are using the primary network interface (index 0). */
    status = nxd_ipv6_address_set(&client_ip, iface_index, NX_NULL, 10, &address_index);

    /* Check for link local address set error.  */
    if (status != NX_SUCCESS)
    {

        error_counter++;
        return;
     }

     /* Set the host global IP address. We are assuming a 64
       bit prefix here but this can be any value (< 128). */
    status = nxd_ipv6_address_set(&client_ip, iface_index, &client_ip_address, 64, &address_index);

    /* Check for global address set error.  */
    if (status != NX_SUCCESS)
    {

        error_counter++;
        return;
     }

    /* Let NetX Duo validate the addresses. */
    tx_thread_sleep(400);

#endif  /* USE_IPV6 */

    /* Create an FTP client.  */
    status =  nx_ftp_client_create(&ftp_client, "FTP Client", &client_ip, 2000, &client_pool);

    /* Check status.  */
    if (status != NX_SUCCESS)
    {

        error_counter++;
        return;
     }

    printf("Created the FTP Client\n");

#ifdef USE_IPV6

    do
    {

        /* Now connect with the NetX Duo FTP (IPv6) server. */
        status =  nxd_ftp_client_connect(&ftp_client, &server_ip_address, "name", "password", 100);
    } while (status != NX_SUCCESS);

#else

    /* Now connect with the NetX FTP (IPv4) server. */
    status =  nx_ftp_client_connect(&ftp_client, FTP_SERVER_ADDRESS, "name", "password", 100);

#endif  /* USE_IPV6 */

    /* Check status.  */
    if (status != NX_SUCCESS)
    {

        error_counter++;
        return;
     }

    printf("Connected to the FTP Server\n");

    /* Open a FTP file for writing.  */
    status =  nx_ftp_client_file_open(&ftp_client, "test.txt", NX_FTP_OPEN_FOR_WRITE, 100);

    /* Check status.  */
    if (status != NX_SUCCESS)
    {

        error_counter++;
        return;
     }

    printf("Opened the FTP client test.txt file\n");

    /* Allocate a FTP packet.  */
    status =  nx_packet_allocate(&client_pool, &my_packet, NX_TCP_PACKET, 100);

    /* Check status.  */
    if (status != NX_SUCCESS)
    {

        error_counter++;
        return;
     }

    /* Write ABCs into the packet payload!  */
    memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ  ", 28);

    /* Adjust the write pointer.  */
    my_packet -> nx_packet_length =  28;
    my_packet -> nx_packet_append_ptr =  my_packet -> nx_packet_prepend_ptr + 28;

    /* Write the packet to the file test.txt.  */
    status =  nx_ftp_client_file_write(&ftp_client, my_packet, 100);

    /* Check status.  */
    if (status != NX_SUCCESS)
    {
        error_counter++;
    }
    else
        printf("Wrote to the FTP client test.txt file\n");


    /* Close the file.  */
    status =  nx_ftp_client_file_close(&ftp_client, 100);

    /* Check status.  */
    if (status != NX_SUCCESS)
        error_counter++;
    else
        printf("Closed the FTP client test.txt file\n");


    /* Now open the same file for reading.  */
    status =  nx_ftp_client_file_open(&ftp_client, "test.txt", NX_FTP_OPEN_FOR_READ, 100);

    /* Check status.  */
    if (status != NX_SUCCESS)
        error_counter++;
    else
        printf("Reopened the FTP client test.txt file\n");

    /* Read the file.  */
    status =  nx_ftp_client_file_read(&ftp_client, &my_packet, 100);

    /* Check status.  */
    if (status != NX_SUCCESS)
        error_counter++;
    else
    {
            printf("Reread the FTP client test.txt file\n");
            nx_packet_release(my_packet);
    }

    /* Close this file.  */
    status =  nx_ftp_client_file_close(&ftp_client, 100);

    if (status != NX_SUCCESS)
        error_counter++;

    /* Disconnect from the server.  */
    status =  nx_ftp_client_disconnect(&ftp_client, 100);

    /* Check status.  */
    if (status != NX_SUCCESS)
        error_counter++;


    /* Delete the FTP client.  */
    status =  nx_ftp_client_delete(&ftp_client);

    /* Check status.  */
    if (status != NX_SUCCESS)
        error_counter++;
}


/* Define the helper FTP server thread.  */
void    thread_server_entry(ULONG thread_input)
{

    UINT            status;
#ifdef  USE_IPV6
    UINT            iface_index, address_index;
#endif

    /* Wait till the IP thread and driver have initialized the system. */
    tx_thread_sleep(100);

#ifdef USE_IPV6

    /* Here's where we make the FTP server IPv6 enabled. */
    status = nxd_ipv6_enable(&server_ip);

    /* Check status.  */
    if (status != NX_SUCCESS)
    {

        error_counter++;
        return;
     }

    status = nxd_icmp_enable(&server_ip);

    /* Check status.  */
    if (status != NX_SUCCESS)
    {

        error_counter++;
        return;
     }

     /* Set the link local address with the host MAC address. */
    iface_index = 0;

    /* This assumes we are using the primary network interface (index 0). */
    status = nxd_ipv6_address_set(&server_ip, iface_index, NX_NULL, 10, &address_index);

    /* Check for link local address set error.  */
    if (status)
    {

        error_counter++;
        return;
     }

    /* Set the host global IP address. We are assuming a 64
       bit prefix here but this can be any value (< 128). */
    status = nxd_ipv6_address_set(&server_ip, iface_index, &server_ip_address, 64, &address_index);

    /* Check for global address set error.  */
    if (status)
    {

        error_counter++;
        return;
     }

    /* Wait while NetX Duo validates the link local and global address. */
    tx_thread_sleep(500);

#endif /* USE_IPV6 */

    /* OK to start the FTP Server.   */
    status = nx_ftp_server_start(&ftp_server);

    if (status != NX_SUCCESS)
        error_counter++;

    printf("Server started!\n");

    /* FTP server ready to take requests! */

    /* Let the IP threads execute.    */
    tx_thread_relinquish();

    return;
}


#ifdef USE_IPV6
UINT  server_login6(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr,
                    NXD_ADDRESS *client_ipduo_address, UINT client_port,
                    CHAR *name, CHAR *password, CHAR *extra_info)
{
    printf("Logged in6!\n");

    /* Always return success.  */
    return(NX_SUCCESS);
}

UINT  server_logout6(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, NXD_ADDRESS *client_ipduo_address,
                     UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info)
{
    printf("Logged out6!\n");

    /* Always return success.  */
    return(NX_SUCCESS);
}
#else
UINT  server_login(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address,
                    UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info)
{

    printf("Logged in!\n");
    /* Always return success.  */
    return(NX_SUCCESS);
}

UINT  server_logout(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address,
                    UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info)
{
    printf("Logged out!\n");

    /* Always return success.  */
    return(NX_SUCCESS);
}
#endif  /* USE_IPV6 */

图 1.1 NetX Duo FTP 示例

配置选项

有几个配置选项可用于构建 NetX FTP 和 NetX Duo FTP。 默认值已列出,但应用程序可以在包括指定的 NetX Duo FTP 头文件之前

设置每个 define。 如果未指定头文件,则该选项在 nxd_ftp_client.h 和 nxd_ftp_server.h 中都可用。 以下列表详细介绍了每个配置选项:

  • NX_FTP_SERVER_PRIORITY:FTP 服务器线程的优先级。 默认情况下,此值定义为 16,表示将优先级指定为 16。
  • NX_FTP_MAX_CLIENTS:服务器可同时处理的最大客户端数。 默认情况下,此值为 4,表示同时支持 4 个客户端。
  • NX_FTP_SERVER_MIN_PACKET_PAYLOAD:服务器数据包池有效负载的最小大小(以字节为单位),包括 TCP、IP 和网络帧标头以及 HTTP 数据。 默认值为 256(FileX 中的最大文件名长度)+ 12 个字节(用于存储文件信息)+ NX_PHYSICAL_TRAILER。
  • NX_FTP_SERVER_TIMEOUT:指定内部服务将暂停的 ThreadX 时钟周期数。 默认值设置为 1 秒 (1 * NX_IP_PERIODIC_RATE)。
  • NX_FTP_ACTIVITY_TIMEOUT:指定不活动时保持客户端连接的秒数。 默认值设置为 240。
  • NX_FTP_TIMEOUT_PERIOD:指定服务器检查客户端活动的间隔(以秒为单位)。 默认值设置为 60。
  • NX_FTP_SERVER_RETRY_SECONDS:指定在重新传输服务器响应之前的初始超时(以秒为单位)。 默认值为 2。
  • NX_FTP_SERVER_TRANSMIT_QUEUE_DEPTH:指定服务器套接字上已排队的传输数据包的最大深度。 默认值为 20。
  • NX_FTP_SERVER_RETRY_MAX:指定每个数据包的最大重试次数。 默认值为 10。
  • NX_FTP_SERVER_RETRY_SHIFT:指定在设置重试超时时要移位的位数。 默认值为 2,例如,每次重试超时都是上一次重试时间的两倍。
  • NX_FTP_NO_FILEX:如果定义了此选项,则可为 FileX 依赖项提供存根。 如果定义了此选项,则无需进行任何更改,FTP 客户端即可正常工作。 FTP 服务器将需要进行修改,或者用户必须创建几个 FileX 服务,FTP 服务器才能正常工作。
  • NX_FTP_CONTROL_TOS:FTP 控制请求所需的服务类型。 默认情况下,此值定义为 NX_IP_NORMAL,表示正常的 IP 数据包服务。
  • NX_FTP_DATA_TOS:FTP 数据请求所需的服务类型。 默认情况下,此值定义为 NX_IP_NORMAL,表示正常的 IP 数据包服务。
  • NX_FTP_FRAGMENT_OPTION:为 FTP 请求启用分段。 默认情况下,此值为 NX_DONT_FRAGMENT,表示禁用 FTP TCP 分段。
  • NX_FTP_CONTROL_WINDOW_SIZE:TCP 控制套接字窗口大小。 默认情况下,此值为 400 个字节。
  • NX_FTP_DATA_WINDOW_SIZE:TCP 数据套接字窗口大小。 默认情况下,此值为 2048 个字节。
  • NX_FTP_TIME_TO_LIVE:指定数据包在被丢弃之前可通过的路由器数目。 默认值设置为 0x80。
  • NX_FTP_USERNAME_SIZE:指定客户端提供的“用户名”中允许的字节数。 默认值设置为 20。
  • NX_FTP_PASSWORD_SIZE:指定客户端提供的“密码”中允许的字节数。 默认值设置为 20。