用C ++发送TFTP包

时间:2015-07-22 10:01:57

标签: c++ udp client tftp

我对C ++比较陌生,所以请原谅我缺乏知识。我需要有关TFTP数据包的帮助。下面是我用来生成WRQ(写请求包)和DATA包的代码,它将被发送到指定的服务器。

override func animationDidStop(anim: CAAnimation!, finished flag: Bool) {

    self.toColors = self.fromColors;
    self.fromColors = self.gradient?.colors
    animateLayer()
}

我将包含声明和所需的功能。

bool createWRQ(char * filename)  {
  /*  structure is the same as RRQ  */
  clear();
  addWord(TFTP_OPCODE_WRITE);
  addString(filename);
  addByte(0);
  addString(TFTP_DEFAULT_TRANSFER_MODE);
  addByte(0);
  return true;
}

bool createData(int block, char * mData, int data_size)  {
  /*      2 bytes    2 bytes       n bytes
  ----------------------------------------
   DATA  | 03    |   Block #  |    Data    |
  ---------------------------------------- */

  clear();                     // to clean the memory location
  addWord(TFTP_OPCODE_DATA);
  addWord(block);
  addMemory(mData, data_size);
  return true;
}

我知道这些函数主要被声明为bool类型,但是我需要向服务器发送一个WRQ数据包并在发送DATA数据包之前等待ACK响应。

有些事情:

#include "stdafx.h"
#include "WebComm.h"
#include "WebCommDlg.h"
#include <stdio.h>
#include <stdlib.h>
#include "visa.h"
#include <cstring>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <winsock.h>
#include <string.h>
#include <string>
#include <fstream>
#include <cstdio>
#include <cerrno>

int      mCurPacketSize = 512;
char     mData[512]; 

#define VIBUF_LEN 255

#define TFTP_OPCODE_READ     1
#define TFTP_OPCODE_WRITE    2
#define TFTP_OPCODE_DATA     3
#define TFTP_OPCODE_ACK      4
#define TFTP_OPCODE_ERROR    5

#define cTFTPPacket_MAX_SIZE 1024
#define cTFTPPacket_DATA_SIZE 512
#define TFTP_DEFAULT_TRANSFER_MODE "octet" //"netascii", "octet", or "mail"

typedef unsigned char BYTE;
typedef unsigned short WORD;    



bool addByte(BYTE b) {
  if(mCurPacketSize >= cTFTPPacket_MAX_SIZE)
    return false;
  mData[mCurPacketSize] = (unsigned char)b;
  mCurPacketSize++;
  return true;
}


bool addWord(WORD w)  {
    w = htons(w);
  if(!addByte(*(((BYTE*)&w)+1))) 
    return false;
  return !addByte(*((BYTE*)&w));
}

bool addString(char * str)  {
  int n = strlen(str);
  for(int i=0; i<n; i++)
    if(!addByte(str[i])) 
      return false;
  return true;
}



bool addMemory(char * buffer, int len)  {
  bool oStatus = false;

  if(mCurPacketSize + len >= cTFTPPacket_MAX_SIZE)   {
    AfxMessageBox("Packet max size exceeded");
    return false;
  } else {
    memcpy(mData + mCurPacketSize), buffer, len);
    mCurPacketSize += len;
    return true;
  }
}


void clear() {
  mCurPacketSize = 0;
  memset(mData, mCurPacketSize, cTFTPPacket_MAX_SIZE);
}

我的问题是:我如何修改while(/* something */) if(!sendto(socket, WRQ, 512, NULL, (sockaddr*)&Addr, sizeof(struct sockaddr_in)))){ if(!recvfrom(socket, ACK, /* ... */)) sendto(socket, DATA_Packet, 512, NULL, (sockaddr*)&Addr, sizeof(struct sockaddr_in)))); createWRQ()函数,以便我可以将它们作为数据包返回以用于传输,因为bool只返回true或false为1或0。 我需要能够使用winsock发送和接收函数发送它们。为愚蠢的问题道歉。如果有人能指出我正确的方向,我将非常感激。

1 个答案:

答案 0 :(得分:0)

你的整个方法有一些问题......

  1. 依靠

    等功能创建数据包时
    bool addByte(BYTE b) 
    

    他们使用全局变量

    mCurPacketSize, mData
    

    那不好。你可以在这些行上使用一些东西

    int addByte(char* Pkt, int PktIdx, BYTE b) 
    {
     if (PktIdx > cTFTPPacket_MAX_SIZE) 
      {
            return 0;
      }
    Pkt[PktIdx] = (unsigned char)b;
    PktIdx++;
    return PktIdx;
    }
    
  2. 然后你知道Pkt总是数据包的头部,而PktIdx要么是新字节(或字符串)的位置,要么“也”是数据包的大小。

    1. 当您创建具有固定长度结构的数据包(或固定长度标头后跟可变长度有效负载区域)时,最好用“打包”表示固定长度区域(注意内存对齐) C / C ++结构然后填充结构。