YModem協議

源:YModem協議

YModem協議:

?????????YModem協議是由XModem協議演變而來的,每包數據可以達到1024字節,是一個非常高效的文件傳輸協議。

?????????下面先看下YModem協議傳輸的完整的握手過程:先看下圖

?

SENDER:發送方。

RECEIVER:接收方。

第一步先由接收方,發送一個字符'C'

發送方收到'C'后,發送第一幀數據包,內容如下:

SOH?00?FF?Foo.c?NUL[123]?CRC?CRC

1字節SOH:表示本包數據區大小有128字節。如果頭為STX表示本包數據區大小為1024

2字節00:?編號,第一包為00,第二包為01,第三包為02依次累加。到FF后繼續從0循環遞增。

3字節FF:?編號的反碼。?編號為00?對應FF,為01對應FE,以此類推。

4字節到最后兩字節:若第1字節為SOH時有128字節,為STX時有1024字節,這部分為數據區。“Foo.c”?文件名,?超級終端下,在文件名后還有文件大小。官方dome也是因為使用了這個文件大小進行比對。這就是為什么用SecureCRT中的YMODEM協議而無法正確傳輸的原因。在文件名和文件大小之后,如果不滿128字節,以0補滿。

最后兩字節:這里需要注意,只有數據部分參與了效CRC,不包括頭和編碼部分。

?

16CRC效驗,高字節在前,低字節在后。

接收方收到第一幀數據包后,發送ACK正確應答。

然后再發送一個字符'C'

發送方收到'C'后,開始發送第二幀,第二幀中的數據存放的是第一包數據。

接收方收到數據后,發送一個ACK然后等待下一包數據傳送完畢,繼續ACK應答。直到所有數據傳輸完畢。

數據傳輸完畢后,發送方發EOT,第一次接收方以NAK應答,進行二次確認。

發送方收到NAK后,重發EOT,接收方第二次收到結束符,就以ACK應答。

最后接收方再發送一個'C',發送方在沒有第二個文件要傳輸的情況下,

?

發送如下數據

SOH?00?FF?00~00(128)?CRCH?CRCL?

接收方應答ACK后,正式結束數據傳輸。

以上部分,為YMODEM協議的基本操作流程。

?

?

源:ymodem協議c實現

/****************************************Copyright (c)**************************************************                               
**                               Henan Star Hi-Tech CO.,LTD                                       
**                                  All rights reserved. 
** 
**----------------------------------------File Info----------------------------------------------------- 
** 文件名稱: 
** 工程項目: 
** 說    明: 
**  
** 作    者:              日    期: 
** 建立版本:              
** 
**----------------------------------------modification-------------------------------------------------- 
** 作    者: 
** 日    期: 
** 版    本:            標    記: 
** 說    明: 
** 
********************************************************************************************************/ #ifndef __XYMODEM_H_ 
#define __XYMODEM_H_ #define MODEM_MAX_RETRIES   50      //接收等待延時時間 
#define MODEM_CRC_RETRIES   51      //>MODEM_MAX_RETRIES固定為CRC校驗 
#define MODEM_CAN_COUNT     3       //Wait for 3 times CAN before quiting 
#define MODEM_EOT_COUNT     1 #define MODEM_SOH  0x01        //數據塊起始字符 
#define MODEM_STX  0x02 
#define MODEM_EOT  0x04 
#define MODEM_ACK  0x06 
#define MODEM_NAK  0x15 
#define MODEM_CAN  0x18 
#define MODEM_C    0x43 typedef struct{ int           modemtype; int           crc_mode; int           nxt_num;          //下一數據塊序號 int           cur_num;          //當塊序號 int           len; int           rec_err;          //數據塊接收狀態 unsigned char buf[1024];        //數據 unsigned int  filelen;          //Ymodem可有帶文件名稱和長度 unsigned char filename[32]; 
}modem_struct; #ifdef __cplusplus extern "C"{ 
#endif int ymodem_init(modem_struct *mblock); 
int modem_recvdata(modem_struct *mblock); 
//int crc_16(unsigned char *buf, int len); 
void modem_cancle(void); 
#ifdef __cplusplus } 
#endif #endif 
/****************************************Copyright (c)**************************************************                                
**                               Henan Star Hi-Tech CO.,LTD                                        
**                                  All rights reserved.  
**  
**----------------------------------------File Info-----------------------------------------------------  
** 文件名稱:  
** 工程項目:  
** 說    明:  
**   
** 作    者:              日    期:  
** 建立版本:               
**  
**----------------------------------------modification--------------------------------------------------  
** 作    者:  
** 日    期:  
** 版    本:            標    記:  
** 說    明:  
**  
********************************************************************************************************/   #include "xymodem1.h"   
#include "heads.h"   unsigned int buf_filelen(unsigned char *ptr);   /*****************************************************************************************  
** 函數名稱:  
** 函數功能:  
** 入口參數:  
** 返 回 值:  
** 編    寫:        日    期:      版 本 號:  
** 修改歷史:  
******************************************************************************************/   
int ymodem_init(modem_struct *mblock)   
{   int stat;   int max_tries = MODEM_MAX_RETRIES;   int crc_tries =MODEM_CRC_RETRIES;   unsigned char *bufptr = mblock->buf;   unsigned char *namptr = mblock->filename;   mblock->nxt_num = 0;   mblock->modemtype = 2;   mblock->rec_err = 0;   mblock->crc_mode = 1;   while (max_tries-- > 0)   {      stat = modem_recvdata(mblock);   if (0 == stat)              //接收成功   
        {   //file name   while (*bufptr != '\0')   {   *namptr++ = *bufptr++;   }   *namptr = '\0';   bufptr++;   while (*bufptr == ' ')   {   bufptr++;   }   //file length   mblock->filelen = buf_filelen(bufptr);   //other data;   
            Uart_SendByte(MODEM_ACK);   return  0;   }   else if (2 == stat)         //取消傳輸   
        {   return 2;   }   else if (-3 == stat)   {   if (mblock->cur_num == 1)   {   mblock->modemtype = 1;   mblock->nxt_num = 2;   return 1;   }   }   else                   //超時或校驗方式不對   
        {   if (crc_tries-- <= 0)   {   crc_tries = MODEM_CRC_RETRIES;   mblock->crc_mode = (mblock->crc_mode+1) & 1;   }   }   }   return -1;   
}   /*****************************************************************************************  
** 函數名稱:  
** 函數功能:  
** 入口參數:  
** 返 回 值:0:成功接收數據                 -1:接收超時             -2:幀錯誤  -3:幀序號序號錯誤(嚴重錯誤)    1:消息結束              2:取消發送            
** 編    寫:        日    期:      版 本 號:  
** 修改歷史:  
******************************************************************************************/   
int modem_recvdata(modem_struct *mblock)   
{   int stat, hd_found=0, i;   int can_counter=0, eot_counter=0;   unsigned char *in_ptr = mblock->buf;   int cksum;   unsigned char ch, blk, cblk, crch, crcl;   Uart_RxEmpty();                         //接收緩沖區清空   if (mblock->nxt_num == 0)   {   if (mblock->crc_mode)   {   Uart_SendByte(MODEM_C);   }   else   {   Uart_SendByte(MODEM_NAK);   }   }   else   {   if (mblock->rec_err)   {   Uart_SendByte(MODEM_NAK);   }   else   {   if (mblock->nxt_num == 1)   {   if (mblock->crc_mode)   {   Uart_SendByte(MODEM_C);   }   else   {   Uart_SendByte(MODEM_NAK);   }   }   else   {   Uart_SendByte(MODEM_ACK);   }   }   }   while (!hd_found)                               //頭字節   
    {   stat = Uart_RecvByteTimeout(&ch);   if (stat == 0)   {   switch (ch)   {   case MODEM_SOH :   hd_found = 1;   mblock->len = 128;   break;   case MODEM_STX :   hd_found = 1;   mblock->len = 1024;   break;   case MODEM_CAN :   if ((++can_counter) >= MODEM_CAN_COUNT)   {   return 2;   }   break;   case MODEM_EOT :                                //文件傳輸結束   if ((++eot_counter) >= MODEM_EOT_COUNT)   {   Uart_SendByte(MODEM_ACK);   if (mblock->modemtype == 2)         //Ymodem協議為批文件傳輸協議   
                        {   Uart_SendByte(MODEM_C);          //單個文件需 C ACK C后會自動停止傳輸   
                            Uart_SendByte(MODEM_ACK);   Uart_SendByte(MODEM_C);   modem_cancle();               //多個文件強制停止傳輸   
                        }   return 1;   }   break;   default:   break;   }   }   else   {   return -1;   }   }   stat = Uart_RecvByteTimeout(&blk);           //數據塊錯誤或超時   if (stat != 0)   {   return -1;   }   stat = Uart_RecvByteTimeout(&cblk);           //數塊補碼   if (stat != 0)   {   return -1;   }   for (i=0; i < mblock->len ; i++)   {   stat = Uart_RecvByteTimeout(in_ptr++);   if (stat != 0)   {   return -1;   }   }   stat = Uart_RecvByteTimeout(&crch);         //CRC   if (stat != 0)   {   return -1;   }   if (mblock->crc_mode)   {   stat = Uart_RecvByteTimeout(&crcl);                if (stat != 0)   {   return -1;   }   }   if (blk^cblk != 0xff)                          {   return (-2);   }   if (mblock->crc_mode)   {   in_ptr = mblock->buf;   cksum = 0;   for (stat=mblock->len ; stat>0; stat--)   {   cksum = cksum^(int)(*in_ptr++) << 8;   for (i=8; i!=0; i--)   {   if (cksum & 0x8000)   cksum = cksum << 1 ^ 0x1021;   else   cksum = cksum << 1;   }   }   cksum &= 0xffff;   if (cksum != (crch<<8 | crcl))   {   mblock->rec_err = 1;   return (-2);   }   }   else   {   for (i=0; i<mblock->len; i++)                //和校驗方式   
        {   cksum += mblock->buf[i];   }   if ((cksum&0xff)!=crch)   {   mblock->rec_err = 1;   return (-2);   }   }   mblock->cur_num = blk;   if (blk != mblock->nxt_num)                      //blk檢查   
    {    return (-3);   }   mblock->nxt_num++;   mblock->rec_err = 0;   return 0;   
}   unsigned int buf_filelen(unsigned char *ptr)   
{   int datatype=10, result=0;   if (ptr[0]=='0' && (ptr[1]=='x' && ptr[1]=='X'))   {   datatype = 16;   ptr += 2;   }   for ( ; *ptr!='\0'; ptr++)   {   if (*ptr>= '0' && *ptr<='9')   {   result =result*datatype+*ptr-'0';   }   else   {   if (datatype == 10)   {   return result;   }   else   {   if (*ptr>='A' && *ptr<='F')   {   result = result*16 + *ptr-55;             //55 = 'A'-10   
                }   else if (*ptr>='a' && *ptr<='f')   {   result = result*16 + *ptr-87;             //87 = 'a'-10   
                }   else   {   return result;   }   }   }   }   return result;   
}   void modem_cancle(void)   
{   Uart_SendByte(0x18);   Uart_SendByte(0x18);   Uart_SendByte(0x18);   Uart_SendByte(0x18);   Uart_SendByte(0x18);   
}  

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/458032.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/458032.shtml
英文地址,請注明出處:http://en.pswp.cn/news/458032.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

gcc、clang、make、cmake、makefile、CMakeLists.txt概念學習

說明 編譯器是翻譯代碼為計算機語言的一個工具&#xff0c;我們平時寫的代碼如果想在某個特定的計算機上執行&#xff08;計算機的cpu構架不同&#xff09;&#xff0c;就需要編譯器來對代碼進行編譯匯編鏈接&#xff0c;而匯編和鏈接的過程對于每個不同的平臺上過程都不一樣。…

視覺在無人駕駛中的應用及分類_機器視覺在智能化生產中的廣泛應用

什么是機器視覺&#xff1f;顧名思義&#xff0c;簡單來說&#xff0c;機器視覺就是用機器代替人眼來測量和判斷。機器視覺系統是指通過機器視覺產品將被攝取目標轉換成圖像信號&#xff0c;傳送給專用的圖像處理系統&#xff0c;根據像素分布和亮度、顏色等信息&#xff0c;轉…

Socket編程實踐(3) 多連接服務器實現與簡單P2P聊天程序例程

SO_REUSEADDR選項 在上一篇文章的最后我們貼出了一個簡單的C/S通信的例程。在該例程序中&#xff0c;使用"Ctrlc"結束通信后&#xff0c;服務器是無法立即重啟的&#xff0c;如果嘗試重啟服務器&#xff0c;將被告知&#xff1a; bind: Address already in use 原因在…

work2的code和問題

//常量 package cn.itcast.work2; public class Constant { //constant 常量   public static void main(String[] args) { /* * 字符串常量 用雙引號括起來的內容 * 整數常量 所有整數 * 小數常量 所有小數 * 字符常量 用單引號括起來的內容,里面只能放單個數字,單個字母或單…

Linux-(C/C++)生成并使用靜態庫/動態庫

靜態庫/動態庫概要 在Windows下靜態庫的后綴為&#xff1a;.lib、動態庫后綴為&#xff1a;.dll&#xff1b;而在Linux下靜態庫的后綴為&#xff1a;.a、動態庫的后綴為&#xff1a;.so。 那么什么是靜態庫呢&#xff1f; 首先我們來看看程序編譯的大體流程&#xff1a;預處理…

windows下最好的圍棋_學圍棋能使學習成績提高嗎?

孩子幾歲開始學習圍棋最合適&#xff1f;當然要4歲開始學圍棋。一是因為&#xff1a;4歲是幼兒形狀知覺形成的關鍵期&#xff0c;圍棋千變萬化的棋形(見文后圖)是最有利于促進與鍛煉孩子形狀知覺的形成。二是因為&#xff1a;人的大腦在3周歲后基本已經發育了60%&#xff0c;到…

每日站立會議05

組員一起討論軟件和關鍵功能的實現&#xff0c;在查詢相關資料、詢問老師、查詢網絡之后&#xff0c;無果。轉載于:https://www.cnblogs.com/zuhaoran/p/5435904.html

C#與C/C++的交互zz

C#與C交互&#xff0c;總體來說可以有兩種方法&#xff1a; 利用C/CLI作為代理中間層 利用PInvoke實現直接調用 第一種方法&#xff1a;實現起來比較簡單直觀&#xff0c;并且可以實現C#調用C所寫的類&#xff0c;但是問題是MONO構架不支持C/CLI功能&#xff0c;因此無法實現脫…

curl查看swift狀態命令_HTTP 請求與響應包括哪些,如何用Chrome查看 HTTP 請求與響應內容和curl 命令的使用...

1.HTTP的請求和響應其實就是通過電腦上的軟件來進行的&#xff0c;客戶端請求的內容發送到服務器上&#xff0c;服務器收到請求后就會響應客戶端的請求&#xff0c;如圖&#xff1a;HTTP請求的內容及格式&#xff1a;請求最多包含四部分&#xff0c;最少包含三部分。&#xff0…

Pytorch的BatchNorm層使用中容易出現的問題

前言 本文主要介紹在pytorch中的Batch Normalization的使用以及在其中容易出現的各種小問題&#xff0c;本來此文應該歸屬于[1]中的&#xff0c;但是考慮到此文的篇幅可能會比較大&#xff0c;因此獨立成篇&#xff0c;希望能夠幫助到各位讀者。如有謬誤&#xff0c;請聯系指出…

android 比較靠譜的圖片壓縮

2019獨角獸企業重金招聘Python工程師標準>>> 第一&#xff1a;我們先看下質量壓縮方法&#xff1a; private Bitmap compressImage(Bitmap image) { ByteArrayOutputStream baos new ByteArrayOutputStream(); image.compress(Bitmap.CompressFormat.JPEG, 100, …

jetty上手

jetty簡介&#xff1a;維基百科 Jetty是一個純粹的基于Java的網頁服務器和Java Servlet容器。盡管網頁服務器通常用來為人們呈現文檔&#xff0c;但是Jetty通常在較大的軟件框架中用于計算機與計算機之間的通信。Jetty支持最新的Java Servlet API&#xff08;帶JSP的支持&#…

常用公差配合表圖_ER彈簧夾頭配套BT刀柄常用規格型號表

ER彈簧夾頭具有定心精度高&#xff0c;夾緊力均勻的特點&#xff0c;廣泛用于機械類零件的精加工和半精加工&#xff0c;通常與BT刀柄匹配使用。BT刀柄是是機械主軸與刀具和其它附件工具連接件&#xff0c;BT為日本標準(MAS403)&#xff0c;現在也是普遍使用的一種標準。傳統刀…

Spatial Transformer Networks(STN)

詳細解讀Spatial Transformer Networks&#xff08;STN&#xff09;-一篇文章讓你完全理解STN了_多元思考力-CSDN博客_stn

Linux下python安裝升級詳細步驟 | Python2 升級 Python3

Linux下python升級步驟 Python2 ->Python3 多數情況下&#xff0c;系統自動的Python版本是2.x 或者yum直接安裝的也是2.x 但是&#xff0c;現在多數情況下建議使用3.x 那么如何升級呢&#xff1f; 下面老徐詳細講解升級步驟&#xff1b; 首先下載源tar包 可利用linux自帶下…

華為手機連電腦_手機、電腦無網高速互傳!華為神技逆天

Huawei Share是華為的一項自研多終端傳輸技術&#xff0c;可以在沒有網絡狀態下實現手機與手機、電腦等多終端設備間快速穩定的文件分享&#xff0c;尤其是在辦公場景下&#xff0c;可以極大提升辦公效率。華為表示&#xff0c;未來Huawei Share將應用于更多全場景跨設備無縫分…

【無標題】移動端深度學習開源框架及部署(對比)

移動端深度學習開源框架及部署 - 凌逆戰 - 博客園

Github基本操作的學習與溫習

GitHub是最先進的分布式版本控制工具&#xff0c;下面是我學習中總結的操作流程&#xff0c;僅供參考 -----------------------------------------------------------------------------------------------------------------------------------------------------------------…

excel統計行數_值得收藏的6個Excel函數公式(有講解)

收藏的Excel函數大全公式再多&#xff0c;幾天不用也會忘記。怎么才能不忘&#xff1f;你需要了解公式的運行原理。小編今天不再推送一大堆函數公式&#xff0c;而是根據提問最多的問題&#xff0c;精選出6個實用的&#xff0c;然后詳細的解釋給大家。1、計算兩個時間差TEXT(B2…

Studio One正版多少錢 Studio One正版怎么購買

隨著版權意識的增強&#xff0c;打擊盜版的力度越來越大&#xff0c;現在網絡上的盜版資源越來越少&#xff0c;資源少很難找是一方面&#xff0c;另一方面使用盜版軟件不僅很多功能不能使用&#xff0c;而且很多盜版軟件都被植入各種木馬病毒&#xff0c;從而帶來各種各樣的風…