udp — отправка пакетов TFTP в переполнении стека

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

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, однако мне нужно отправить пакет WRQ на сервер и дождаться ответа ACK перед отправкой пакета DATA.

Что-то вроде:

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 возвращает только true или false как 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 ++ структура, а затем заполнить структуру.
0

Другие решения


По вопросам рекламы [email protected]