zynq平台tftp客户端
生活随笔
收集整理的這篇文章主要介紹了
zynq平台tftp客户端
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
基于LWIP的UDP示例工程,實現tftp客戶端內容,包含上傳和下載功能。
硬件平臺:zynq 7020
系統:FreeRTOS
bylh_tftp_client_H
/** @Author: 47* @Date: 2022-01-05 11:27:51* @LastEditTime: 2022-01-05 16:45:44* @LastEditors: Please set LastEditors* @FilePath: \src\udp_perf_client.h*/#ifndef __UDP_PERF_CLIENT_H_ #define __UDP_PERF_CLIENT_H_#include "lwipopts.h" #include "lwip/ip_addr.h" #include "lwip/err.h" #include "lwip/udp.h" #include "lwip/inet.h" #include "lwip/sockets.h" #include "lwip/sys.h" #include "errno.h" #include <sleep.h> #include "xil_printf.h" #include "xlwipconfig.h"typedef int (*tftpDownLoadCallback)(char * pData,int dataLen,void * arg);int downloadFile(char * serverIp,char * fileName,tftpDownLoadCallback pTftpDownLoadCallback,void * arg); int uploadFile(char * serverIp,char * destFileName,char * sourceData,long long dataLen); #endif /* __UDP_PERF_CLIENT_H_ */BYLH_TFTP_CPP
/** @Author: 47* @Date: 2022-01-05 11:27:51* @LastEditTime: 2022-01-05 16:22:06* @LastEditors: Please set LastEditors* @FilePath: \src\udp_perf_client.c*/ #include "tftp_client.h" #define TFTP_RRQ 1 //下載 #define TFTP_WRQ 2 //上傳 #define TFTP_DATA 3 //數據 #define TFTP_ACK 4 //ACK #define TFTP_ERROR 5 //Error#define ASCII_FORMAT 1 #define OCTET_FORMAT 2//錯誤種類 #define Not_defined 0 #define File_not_found 1 #define Access_violation 2 #define Disk_full 3 #define Illegal_TFTP_operation 4 #define Unknown_port 5 #define File_already_exists 6 #define No_such_user 7 #define Time_out 8 #define Read_file_Error 9 #define Cannot_create_file 10//#define TFTP_PRINTF_DEBUG //!< lwq 2022 01 05 調試打印開關int sendRequest(int op, const char* filename, int type, int socket) { static char requestBuf[128]; memset(requestBuf, 0, sizeof(requestBuf)); requestBuf[1] = op; strcpy(requestBuf + 2, filename); if (type == OCTET_FORMAT){//!< 操作碼2B + 文件名 (N B)+'\0'(1B)+模式char * formatStr = "octet";strcpy(requestBuf + 2+strlen(filename)+1,formatStr);return send(socket,requestBuf,2+strlen(filename)+1+strlen(formatStr)+1,0);}else{char * formatStr = "netascii";strcpy(requestBuf + 2+strlen(filename)+1,formatStr);return send(socket,requestBuf,2+strlen(filename)+1+strlen(formatStr)+1,0);}return -1; }int makeack(unsigned short num, char *buffer, int size) {buffer[0] = 0;buffer[1] = 0x04; //操作碼為04buffer[2] = (char)(num>>8);//塊號2個字節buffer[3] = (char)(num&0xFF); #ifdef TFTP_PRINTF_DEBUGprintf("%s[%d]%d\r\n",__FUNCTION__,__LINE__,(char)(num>>8));printf("%s[%d]%d\r\n",__FUNCTION__,__LINE__,(char)(num&0xFF)); #endifreturn 4; }int sendAck(unsigned short packNum, int socket) {char send_buffer[10]={0}; #ifdef TFTP_PRINTF_DEBUGprintf("%s[%d]%d\r\n",__FUNCTION__,__LINE__,packNum); #endifint len = makeack(packNum,send_buffer,sizeof(send_buffer));return send(socket,send_buffer,len,0); }int makeerr(unsigned short num,char *buffer) {buffer[0]=0;buffer[1]=TFTP_ERROR;buffer[2] = (char)(num>>8);buffer[3] = (char)num;return 4; }unsigned short transPackNum(unsigned short sorcePackNum) {unsigned short ret;#ifdef TFTP_PRINTF_DEBUGprintf("%s[%d] %x \r\n",__FUNCTION__,__LINE__,sorcePackNum); #endifret = (sorcePackNum>>8)+((sorcePackNum&0xFF)<<8);return ret; }int downloadFile(char * serverIp,char * fileName,tftpDownLoadCallback pTftpDownLoadCallback,void * arg) {struct sockaddr_in addr;if(0==serverIp||fileName==0||pTftpDownLoadCallback==0){return -1;}int sock;err_t err;memset(&addr, 0, sizeof(struct sockaddr_in));addr.sin_family = AF_INET;addr.sin_port = htons(69);addr.sin_addr.s_addr = inet_addr(serverIp);if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {xil_printf("UDP client: Error creating Socket\r\n");return -2;}err = connect(sock, (struct sockaddr *)&addr, sizeof(addr));if (err != ERR_OK) {xil_printf("UDP client: Error on connect: %d\r\n", err);close(sock);return -2;}struct timeval tv_out;tv_out.tv_sec = 5;tv_out.tv_usec = 0;setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &tv_out, sizeof(tv_out));if(sendRequest(TFTP_RRQ,fileName,OCTET_FORMAT,sock)){long long recvDatLen = 0;int dataCacheLen = 0;char * fileDataCache = (char*)malloc(520);char * recvData = (char*)malloc(600);unsigned short lastPackNum = -1;while(1){int recvLen = recv(sock,recvData,600,0);printf("%d\r\n",recvLen);if(recvLen>0){if(TFTP_DATA == recvData[1]){unsigned short currentPackNum = transPackNum(((unsigned short*)recvData)[1]);#ifdef TFTP_PRINTF_DEBUGprintf("currentPackNum %x %x %x\r\n",currentPackNum,recvData[2],recvData[3]); #endifif((unsigned short)(-1)==lastPackNum||lastPackNum+1==currentPackNum||(lastPackNum==65535&&0==currentPackNum)){#ifdef TFTP_PRINTF_DEBUGprintf("%s[%d]%d\r\n",__FUNCTION__,__LINE__,lastPackNum); #endiflastPackNum = currentPackNum;recvDatLen+=(recvLen-4);{//!< callbackDataif(dataCacheLen){//!<TODO 上一次數據回調出去pTftpDownLoadCallback(fileDataCache,dataCacheLen,arg);dataCacheLen = 0;}//!< 緩存當前數據memcpy(fileDataCache,recvData+4,recvLen-4);dataCacheLen = recvLen-4;}sendAck(currentPackNum,sock);if(recvLen<4+512){if(dataCacheLen){//!<TODO 上一次數據回調出去pTftpDownLoadCallback(fileDataCache,dataCacheLen,arg);dataCacheLen = 0;}dataCacheLen = recvLen-4;memcpy(fileDataCache,recvData+4,recvLen-4);if(dataCacheLen){//!<TODO 最后一次數據回調出去pTftpDownLoadCallback(fileDataCache,dataCacheLen,arg);dataCacheLen = 0;}printf("%lldByte\r\n",recvDatLen);puts("recv Finish!!!");break;}}else{//error#ifdef TFTP_PRINTF_DEBUGprintf("%s[%d]%d\r\n",__FUNCTION__,__LINE__,lastPackNum); #endifsendAck(lastPackNum,sock);}}}else if(recvLen<0){break;}}free(recvData);free(fileDataCache);}close(sock);return 0; } //Data包填充 int makedata(unsigned short num,char *data,long long datasize,long long currentPos,char *buffer,int bufsize) {int pos = 0;buffer[pos] = 0;pos++;buffer[pos] = TFTP_DATA; //操作碼為03pos++;buffer[pos] = (char)(num>>8);//塊號pos++;buffer[pos] = (char)num; pos++;datasize = (datasize-currentPos)>512?512:(datasize-currentPos);memcpy(&buffer[pos],data+currentPos,datasize);//填充數據pos = pos + datasize;return pos; }int uploadFile(char * serverIp,char * destFileName,char * sourceData,long long dataLen) {struct sockaddr_in addr;if(0==serverIp||destFileName==0||sourceData==0||dataLen==0)return -1;int sock;err_t err;memset(&addr, 0, sizeof(struct sockaddr_in));addr.sin_family = AF_INET;addr.sin_port = htons(69);addr.sin_addr.s_addr = inet_addr(serverIp);if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {xil_printf("UDP client: Error creating Socket\r\n");return -2;}err = connect(sock, (struct sockaddr *)&addr, sizeof(addr));if (err != ERR_OK) {xil_printf("UDP client: Error on connect: %d\r\n", err);close(sock);return -2;}if(sendRequest(TFTP_WRQ,destFileName,OCTET_FORMAT,sock)){long long currentPos = 0;char * dataPack = (char *)malloc(600);char * recvData = (char*)malloc(64);unsigned short lastPackNum = -1;while(1){int recvLen = recv(sock,recvData,64,0);if(recvLen>0){if(TFTP_ACK == recvData[1]){unsigned short currentPackNum = transPackNum(((unsigned short*)recvData)[1]);currentPackNum++;//發送第一個包int packLen = makedata(currentPackNum,sourceData,dataLen,currentPos,dataPack,600);send(sock,dataPack,packLen,0);if(packLen<4+512){puts("Send Finish!!");break;}}else if(TFTP_ERROR == recvData[1]){printf("TFTP ERROR(CODE = %d)\r\n",recvData[3]);close(sock);free(recvData);free(dataPack);return -3;}}}close(sock);free(recvData);free(dataPack);}return 0; }總結
以上是生活随笔為你收集整理的zynq平台tftp客户端的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 视力保健远眺图_陕南赤子_新浪博客
- 下一篇: Linux TFTP