Я относительно новичок в 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. Извиняюсь за глупый вопрос. Если бы кто-нибудь мог указать мне правильное направление, я был бы очень признателен.
у всего вашего подхода есть несколько проблем …
Когда вы создаете свои пакеты, полагаясь на такие функции, как
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 — это либо место для нового байта (или строки), а также «размер» пакета.