2015-07-22 4 views
0

Я относительно новичок в C++, поэтому, пожалуйста, простите мне недостаток знаний. Мне нужна помощь в отношении пакетов TFTP. Ниже приведен код, который я использую для создания пакета запросов WRQ (пакет запроса на запись) и DATA, который будет отправлен на указанный сервер.Отправка пакетов TFTP в C++

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; 
} 

Я буду включать декларации и необходимые функции.

#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); 
} 

Я знаю, эти функции были объявлены в основном как тип BOOL, однако мне нужно послать пакет ВРК на сервер и ждать ответа ACK перед отправкой пакета данных.

Что-то вдоль линий:

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() и createData() функции, так что я могу вернуть их в пакеты, чтобы использовать для передачи, так как BOOL только возвращает истину или ложь как 1 или 0. Мне нужно иметь возможность отправлять их с помощью функций отправки и получения winsock. Извиняюсь за глупый вопрос. Если бы кто-нибудь мог указать мне в правильном направлении, я был бы очень признателен.

ответ

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; 
    } 
    

, то вы знаете, что Pkt всегда головка вашего пакета и PktIdx либо место для нового байта (или строки) и «также» размер пакета.

  1. При создании пакетов, имеющих структуру с фиксированной длиной (или заголовок с фиксированной длиной, за которым следует область полезной нагрузки переменной длины), рекомендуется представлять область фиксированной длины с помощью «упакован» (обратите внимание на выравнивание памяти) структуру C/C++, а затем заполнить структуру.
Смежные вопросы