2010-10-12 6 views
3

У меня есть класс для заголовка RDT, который содержит информацию для реализации нескольких надежных протоколов передачи данных. Мне нужно прикрепить эту информацию (всего 12 байт) к моему буферу отправки, чтобы передать его по сокету. Я пытаюсь использовать memcpy для этого, но по какой-то причине он просто оставляет мусор в буфере. Ниже приведена строка кода, которая не работает. (RDT_HDR_SIZE определяется как 12).Почему memcpy не работает должным образом?

Определение переменных, передаваемых этой функции.

char payload[] = "sample code sample code"; 
int payload_size = sizeof(payload) ; 
int pktsize = payload_size + sizeof(RdtHeader)+1 ; // 1 byte for NULL-terminated 
char * send_buf = new char[pktsize]; 

Функция с memcpy, которая имеет проблемы.

unsigned int Sender::CreateSegment(char * buf, 
     char payload[], int payload_size, unsigned long seqnum) { 
    RdtHeader * header = (RdtHeader *) buf; 
    // set rdt fields: 
    header->ack = 0; 
    header->fin = 0; 
    header->ok = 0; 
    header->seq = seqnum; 
    header->win = 0; 
    header->syn = 0; 
    memcpy(buf+RDT_HDR_SIZE, payload, payload_size); 

    return (payload_size + RDT_HDR_SIZE + 1); 
} 

Если я вынимаю RDT_HDR_SIZE, полезную нагрузке назначается правильно BUF, однако он стирает все мои поля заголовка. Любая идея, как заставить это работать?

Спасибо,

Eric R.

EDIT:

Вот код для моего класса RdtHeader - возможно, это будет полезно.

class RdtHeader{ // 12-byte header 
public: 
//1-byte flags field 
    u_char protocol:2;  // 2 bits: protocol type = 0 for RDT3, 1 for GBN, and 2 for STCP  
    u_char syn:1;   // 1 bit: SYN = 1 for connection setup 
    u_char fin:1;   // 1 bit: FIN = 1 for termination 
    u_char ok:1;   // 1 bit: OK = 1 receiver agrees, SYN_OK or FIN_OK 
    u_char reserved:3;  // 3 bits: unused 

    u_char unused;   // 1-byte unused filed; 

    u_short win;   // 2-byte receiver window size (the number of packets) 
    u_long seq;    // 4-byte sequence number 
    u_long ack;    // 4-byte ack number 
}; 
+0

Вы пробовали использовать SizeOf (RdtHeader), а не жесткого кодирования размер буфера? – 2010-10-12 04:31:08

ответ

2

Это может быть слишком очевидно, но как именно вы проверяете буфер?

Вы пробовали

printf("%s\n", send_buf + sizeof(RdtHeader)); 

?

Если вместо этого вы делаете ...

printf("%s\n", send_buf); 

... то вы должны ожидать видеть только мусор (с правильной эксплуатацией), так как win поля действует как нуль-терминатор для «строк «что этот последний вызов печатает.

Приветствия & НТН,

-. Альф

+1

/facepalm --- Хорошо, так что в основном мораль этой истории заключается в том, что я технически дал ей нулевой ограничитель при назначении значений моему RdtHeader. Спасибо, что указали это. Я просто не мог понять, почему мой memcpy не работал, когда я чувствовал, что все должно быть хорошо. Оксеймс Бритва ... Не была копия, но как я увидел, что было скопировано. –

2

Как отметил Марк, посмотрите на sizeof (RdtHeader). Внутри структуры может быть некоторое дополнение (тем более, что там есть длинный int), который отбрасывает вычисления.

Но кроме этого я не вижу здесь очевидной проблемы. Я бы попытался добавить некоторые распечатки, если вы запускаете его в среде, где это возможно, или попробуйте отладчик. Возможно, настоящая проблема в другом месте вашего кода.

+0

Я пробовал memcpy (buf + sizeof (RdtHeader), полезную нагрузку, payload_size) и до сих пор не копирует. Он просто оставляет мусор в буфере. Я поместил printf сразу после memcpy и не имел полезной нагрузки. Я отредактировал исходное сообщение и добавил определение моего класса для RdtHeader. –

0
memcpy(header + 1, payload, payload_size + 1); 
return sizeof(*header) + payload_size + 1; 
  • Вы загадочно возвращающий дополнительный 1, что указывает на полезную нагрузку является завершающуюся нулем строку. Вы могли бы хотите скопировать этот терминатор, так что это , включенный в последние memcpy параметр.
  • С помощью указателя header для расчета адресата memcpy вам не придется бросать, если типы меняются, в частности, если вы меняете тип buf. Вы можете положиться на то, что C++ позволяет X * разделиться на void *, чтобы избежать уродливого литья.
+0

. Не 100% уверены, что вы подразумеваете под этим. Используя код, который вы указали, изменений в выходе нет. У моего буфера все еще есть мусор. Если я удалю добавление в указателях в memcpy (будь то с использованием заголовка или buf), полезная нагрузка будет скопирована отлично, но я потеряю всю информацию о моем заголовке. –

Смежные вопросы