女人自慰AV免费观看内涵网,日韩国产剧情在线观看网址,神马电影网特片网,最新一级电影欧美,在线观看亚洲欧美日韩,黄色视频在线播放免费观看,ABO涨奶期羡澄,第一导航fulione,美女主播操b

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

基于UDP的簡單文件傳輸協議TFTP設計

CHANBAEK ? 來源:木南創智 ? 作者:尹家軍 ? 2022-12-14 15:06 ? 次閱讀

前面我們已經實現了UDP的回環客戶端和回環服務器的簡單應用,接下來我們實現一個基于UDP的簡單文件傳輸協議TFTP。

1 TFTP****協議簡介

TFTP是TCP/IP協議族中的一個用來在客戶機與服務器之間進行簡單文件傳輸的協議,提供不復雜、開銷不大的文件傳輸服務。端口號為69

TFTP是一種簡單的文件傳輸協議。目標是在UDP之上上建立一個類似于FTP的但僅支持文件上傳和下載功能的傳輸協議,所以它不包含FTP協議中的目錄操作和用戶權限等內容。

TFTP報文的頭兩個字節表示操作碼,共有5中操作碼,如下表:

讀請求和寫請求功能碼的數據報文格式是一樣的,所以TFTP報文又可表述為4種形式。對于讀請求或者寫請求,文件名字段說明客戶要讀或寫的位于服務器的上的文件并以0字節作為結束,模式字段是一個ASCII碼串,同樣以0字節結束。讀請求和寫請求的報文格式:

其次是數據包,起包括2個字節的塊編號以及0-512個字節的數據信息。數據包相對比較簡單,其報文格式:

再者為確認包。確認包也有2個字節的塊編號。其數據格式:

最后一種TFTP報文類型是差錯報文,它的操作碼為5.它用于服務器不能處理讀請求或者寫請求的情況。在文件傳輸的過程中的讀和寫也會導致傳送這種報文,接著停止傳輸。錯誤包的報文格式:

TFTP的工作過程很像停止等待協議,發送完一個文件塊后就等待對方的確認,確認時應指明所確認的塊號。發送完數據后在規定時間內收不到確認就要重發數據PDU,發送確認PDU的一方若在規定時間內收不到下一個文件塊,也要重發確認PDU。這樣保證文件的傳送不致因某一個數據報的丟失而告失敗。

2 TFTP****協議棧設計

前面我們簡單的介紹了TFTP協議,接下來我們看看該如何實現其編程。它有5種操作碼,我們要做的就是實現對這5種操作碼的響應。

2.1 、讀請求實現

所謂讀請求,就是客戶端請求從服務器獲取文件,那么服務器需要做的自然是響應客戶端的請求。但我們并沒有文件,所以不管它請求什么文件,我們均給它返回內容和大小相同的測試文件。

1 /* TFTP讀請求處理*/
 2 int TftpReadProcess(struct udp_pcb *upcb, const ip_addr_t *to, int to_port, char* FileName)
 3 {
 4   tftp_connection_args *args = NULL;
 5  
 6   /* 這個函數在回調函數中被調用,因此中斷被禁用,因此我們可以使用常規的malloc */
 7   args = mem_malloc(sizeof(tftp_connection_args));
 8  
 9   if (!args)
10   {
11     /* 內存分配失敗 */
12     SendTftpErrorMessage(upcb, to, to_port, TFTP_ERR_NOTDEFINED);
13  
14     CleanTftpConnection(upcb, args);
15  
16     return 0;
17   }
18  
19   /* i初始化連接結構體  */
20   args->op = TFTP_RRQ;
21   args->remote_port = to_port;
22   args->block = 1; /* 塊號從1開始 */
23   args->tot_bytes = 10*1024*1024;
24  
25   /* 注冊回調函數 */
26   udp_recv(upcb, RrqReceiveCallback, args);
27  
28   /* 通過發送第一個塊來建立連接,后續塊在收到ACK后發送*/
29    SendNextBlock(upcb, args, to, to_port);
30  
31   return 1;
32 }

2.2 、寫請求實現

寫請求就是客戶端希望向服務器傳送文件,在這里我們只是實現TFTP服務器的功能,沒必要將收到的文件真正保存到一個地方,所以只是做接收文件的過程并不將其寫到存儲器,簡單的說就是只在內存中而不會寫入Flash等。

1 /* TFTP寫請求處理 */
 2 int TftpWriteProcess(struct udp_pcb *upcb, const ip_addr_t *to, int to_port, char *FileName)
 3 {
 4   tftp_connection_args *args = NULL;
 5  
 6   /* 這個函數在回調函數中被調用,因此中斷被禁用,因此我們可以使用常規的malloc */
 7   args = mem_malloc(sizeof(tftp_connection_args));
 8  
 9   if (!args)
10   {
11     SendTftpErrorMessage(upcb, to, to_port, TFTP_ERR_NOTDEFINED);
12  
13     CleanTftpConnection(upcb, args);
14  
15     return 0;
16   }
17  
18   args->op = TFTP_WRQ;
19   args->remote_port = to_port;
20   args->block = 0;      //WRQ響應的塊號為0
21   args->tot_bytes = 0;
22  
23   /* 為控制塊注冊回調函數 */
24   udp_recv(upcb, WrqReceiveCallback, args);
25  
26   /* 通過發送第一個ack來發起寫事務 */
27   SendTftpAckPacket(upcb, to, to_port, args->block);
28  
29   return 0;
30 }

2.3 、數據包操作

無論是讀請求還是寫請求,最終的目的無非是要傳送數據,所以數據包自然也是我們需要構造和傳送的。其對應的就是數據包操作碼,我們設計程序如下:

1 /* 構造并且傳送數據包 */
 2 static int SendTftpDataPacket(struct udp_pcb *upcb, const ip_addr_t *to, int to_port, int block,char *buf, int buflen)
 3 {
 4   /* 將開始的2個字節設置為功能碼 */
 5   SetTftpOpCode(buf, TFTP_DATA);
 6  
 7   /* 將后續2個字節設置為塊號 */
 8   SetTftpBlockNumber(buf, block);
 9  
10   /* 在后續設置n個字節的數據 */
11  
12   /* 發送數據包 */
13   return SendTftpMessage(upcb, to, to_port, buf, buflen + 4);
14 }

2.4 、確認包操作

在傳送數據包后,收到沒收到,發送方是不知道的,怎么辦呢?這時候接受方接收到后,會給出一個確認包。其對應的就是確認操作碼,那么我們還需實現確認包的構造和發送。

1 /*構造并發送確認包*/
 2 int SendTftpAckPacket(struct udp_pcb *upcb,const ip_addr_t *to, int to_port, int block)
 3 {
 4   /* 創建一個TFTP ACK包 */
 5   char packet[TFTP_ACK_PKT_LEN];
 6  
 7   /* 將開始的2個字節設置為功能碼 */
 8   SetTftpOpCode(packet, TFTP_ACK);
 9  
10   /* 制定ACK的塊號 */
11   SetTftpBlockNumber(packet, block);
12  
13   return SendTftpMessage(upcb, to, to_port, packet, TFTP_ACK_PKT_LEN);
14 }

2.5 、錯誤包操作

在包傳送的過程中,有沒有可能出現錯誤呢?當然是有的,這就需要所謂的錯誤包操作碼。在服務器不能處理讀請求或者寫請求的情況下。在文件傳輸的過程中的讀和寫也會導致傳送這種報文,接著停止傳輸。我們也需要開發構造和傳送錯誤包的函數。

1 /* 構造并向客戶端發送一條錯誤消息 */
 2 static int SendTftpErrorMessage(struct udp_pcb *upcb, const ip_addr_t *to, int to_port, tftp_errorcode err)
 3 {
 4   char buf[512];
 5   int error_len;
 6  
 7   error_len = ConstructTftpErrorMessage(buf, err);
 8  
 9   return SendTftpMessage(upcb, to, to_port, buf, error_len);
10 }

3 TFTP****服務器實現

我們已經實現了UDP服務器,而且也實現了簡單的TFTP協議棧,接下來的工作就是在UDP基礎上實現TFTP服務器功能。前面我們已經提到過,復雜的服務器應用只是回到函數的功能不一樣,所以開發的過程并無區別。

首先我們來實現初始化部分。創建新的UDP控制塊。綁定到制定的服務器端口,我們要實現TFTP服務器,而TFTP協議的端口號為69,所以我們將其綁定到該端口。最后注冊TFTP服務器的回調函數。

1 /* 初始化TFTP服務器 */
 2 void Tftp_Server_Initialization(void)
 3 {
 4   err_t err;
 5   struct udp_pcb *tftp_server_pcb = NULL;
 6  
 7   /* 生成新的 UDP PCB控制塊 */
 8   tftp_server_pcb = udp_new();
 9  
10   /* 判斷UDP控制塊是否正確生成 */
11   if (NULL == tftp_server_pcb)
12   { 
13     return;
14   }
15  
16   /* 綁定PCB控制塊到指定端口 */
17   err = udp_bind(tftp_server_pcb, IP_ADDR_ANY, UDP_TFTP_SERVER_PORT);
18  
19   if (err != ERR_OK)
20   {
21     udp_remove(tftp_server_pcb);
22     return;
23   }
24  
25   /* 注冊TFTP服務器處理函數 */
26   udp_recv(tftp_server_pcb, TftpServerCallback, NULL);
27 }

在初始化中注冊了回調函數,所以我們還要實現TFTP服務器的回調函數。這部分出于結構清晰的考慮,我們分成兩個函數來寫。

1 /* TFTP服務器回調函數 */
 2 static void TftpServerCallback(void *arg, struct udp_pcb *upcb, struct pbuf *p,const ip_addr_t *addr, u16_t port)
 3 {
 4   /* 處理新的連接請求 */
 5   ProcessTftpRequest(p, addr, port);
 6  
 7   pbuf_free(p);
 8 }
 9 /* 從每一個來自addr:port的新請求創建一個新的端口來服務響應,并啟動響應過程 */
10 static void ProcessTftpRequest(struct pbuf *pkt_buf, const ip_addr_t *addr, u16_t port)
11 {
12   tftp_opcode op = ExtractTftpOpcode(pkt_buf->payload);
13   char FileName[50] = {0};
14   struct udp_pcb *upcb = NULL;
15   err_t err;
16  
17   /* 生成新的UDP PCB控制塊 */
18   upcb = udp_new();
19   if (!upcb)
20   {
21     return;
22   }
23  
24   /* 連接 */
25   err = udp_connect(upcb, addr, port);
26   if (err != ERR_OK)
27   { 
28     return;
29   }
30  
31   ExtractTftpFilename(FileName, pkt_buf->payload);
32  
33   switch (op)
34   {
35   case TFTP_RRQ:
36     {
37  
38       TftpReadProcess(upcb, addr, port, FileName);
39       break;
40     }
41   case TFTP_WRQ:
42     {
43       /* 啟動TFTP寫模式 */
44       TftpWriteProcess(upcb, addr, port, FileName);
45       break;
46     }
47   default:
48     {
49       /* 異常,發送錯誤消息 */
50       SendTftpErrorMessage(upcb, addr, port, TFTP_ERR_ACCESS_VIOLATION);
51  
52       udp_remove(upcb);
53  
54       break;
55     }
56   }
57 }

在回調函數中,我們實現了對TFTP讀請求和寫請求的響應,但這足以驗證我們想要實現的TFTP服務器的功能。

4 、結論

本篇我們基于LwIP的UDP實現了一個簡單的FTP服務器。這個FTP服務器只是實現FTP協議的功能,具體的應用可根據需要添加。我們使用了TFTP客戶端工具對這一服務器進行了基本測試,最終結果符合我們的預期。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 服務器
    +關注

    關注

    13

    文章

    9702

    瀏覽量

    87318
  • TFTP
    +關注

    關注

    0

    文章

    22

    瀏覽量

    14502
  • UDP
    UDP
    +關注

    關注

    0

    文章

    330

    瀏覽量

    34482
  • 文件傳輸協議

    關注

    0

    文章

    3

    瀏覽量

    938
收藏 人收藏

    評論

    相關推薦
    熱點推薦

    STM32物聯網之TFTP文件傳輸

    TFTP協議理解從以上兩張圖片,我們了解到什么有用信息呢?每一次文件傳輸,首先需要發起一個請求,根據請求幀的操作碼判斷是讀文件還是寫文件
    發表于 12-30 15:44

    第38章 TFTP簡單文件傳輸基礎知識

    轉帖本章節為大家講解TFTP(TrivialFile Transfer Protocol,簡單文件傳輸協議)的基礎知識,方便后面章節的實戰操作。(本章的知識點主要整理自網絡)38.1
    發表于 12-22 08:57

    TFTP協議

    Protocol,簡單文件傳輸協議)是TCP/IP協議族中的一個用來在客戶端與服務器之間進行簡單文件傳
    發表于 11-05 09:14

    基于TFTP文件傳輸協議實現STM32F407局域網內遠程網絡升級

    版本。在學習本技術前,應以熟悉TCP/IP中UDP協議,面向無連接,可支持同時多設備在線同時TFTP遠程升級。BootLoader_TFTP程序下載:APP應用程序:Tftpd64工具
    發表于 01-12 06:29

    tftp文件傳輸出現遠程主機強制關閉了是怎么回事?

    用的是開發板通過網線連著電腦做調試。兩個設備間的相互ping都是沒有問題。包括TCP和UDP的各種模式都測過,沒有問題。開發板的文件系統都已經有了,但是在調tftp文件傳輸的時候,發現
    發表于 02-23 15:14

    TFTP服務器是什么如何下載文件

    服務,復雜度和開銷都很小。 Tftp是什么 tftp是一個傳輸文件簡單協議,它基于
    發表于 12-12 16:06

    TFTP簡單文件傳送協議

    TFTP簡單文件傳送協議:T F T P ( Trivial File Transfer Protocol)即簡單
    發表于 09-20 17:59 ?15次下載

    什么是TFTP

    什么是TFTP  英文原義:Trivial File Transfer Protocol 中文釋義:簡單文件傳輸協議或零碎文件傳輸
    發表于 02-23 11:25 ?2162次閱讀

    TFTP協議

    TFTP 是一個傳輸文件簡單協議,它其于UDP 協議
    發表于 03-02 16:03 ?34次下載

    TCP協議UDP協議的區別和相同點有哪些 一文看懂TCP協議UDP協議的優缺點

    。里面包括很多協議的。UDP只是其中的一個。之所以命名為TCP/IP協議,因為TCP,IP協議是兩個很重要的協議,就用他兩命名了。 TCP/
    的頭像 發表于 05-26 14:35 ?1w次閱讀
    TCP<b class='flag-5'>協議</b>與<b class='flag-5'>UDP</b><b class='flag-5'>協議</b>的區別和相同點有哪些 一文看懂TCP<b class='flag-5'>協議</b>與<b class='flag-5'>UDP</b><b class='flag-5'>協議</b>的優缺點

    Linux下部署TFTP服務

    TFTP是 Trivial File Transfer Protocol 的縮寫,即簡單文件傳輸協議,是一個基于 UDP
    的頭像 發表于 04-17 14:56 ?1376次閱讀
    Linux下部署<b class='flag-5'>TFTP</b>服務

    rtthread中使用lwip自帶的tftp功能傳輸文件

    TFTP簡單文件傳輸協議)是TCP/IP協議族中的一個用來在客戶機與服務器之間進行文件傳輸
    發表于 07-22 14:06 ?1513次閱讀
    rtthread中使用lwip自帶的<b class='flag-5'>tftp</b>功能<b class='flag-5'>傳輸</b><b class='flag-5'>文件</b>

    RT-Thread中使用lwip自帶的tftp功能傳輸文件

    TFTP協議 TFTP簡單文件傳輸協議)是TCP/IP協議
    的頭像 發表于 07-24 19:35 ?2144次閱讀
    RT-Thread中使用lwip自帶的<b class='flag-5'>tftp</b>功能<b class='flag-5'>傳輸</b><b class='flag-5'>文件</b>

    FTP、SFTP、TFTP文件傳輸協議之間的主要區別

    FTP(File Transfer Protocol,文件傳輸協議)是用于在計算機網絡中傳輸文件的標準協議
    的頭像 發表于 11-15 09:04 ?8271次閱讀
    FTP、SFTP、<b class='flag-5'>TFTP</b><b class='flag-5'>文件傳輸</b><b class='flag-5'>協議</b>之間的主要區別

    FTP文件傳輸協議的工作模式

    FTP(File Transfer Protocol)文件傳輸協議,基于C/S架構,支持文件的上傳和下載功能。
    的頭像 發表于 02-06 10:09 ?544次閱讀