сокеты — потери данных при преобразовании структуры в байтовый массив и отправке его по UDP в Stack Overflow

У меня есть клиент, который хочет отправить сообщение на сервер через UDP.

У меня есть структура сообщения:

struct Msg1
{
uint8_t tag = 1;
uint32_t nonce = 0;
uint16_t length = 0;
char *name;
};

Я конвертирую его в массив uint32_t, отправляю по UDP и реконвертирую. Но вывод:

1 Byte: TAG:
4 Byte: NONCE: 1111111
2 Byte: LENGTH: 5
8 Byte: NAME:

Теперь я запутался, потому что две переменные верны, а две нет. Может быть, у кого-то есть идея?

// РЕДАКТИРОВАТЬ файлы примеров

/* Client.cpp */

#include "Client.h"#include <gmp.h>

Client::Client(){}

void Client::start()
{
this->prepareMsg1();
this->sendMsg1();
}

void Client::prepareMsg1()
{
// generate random Na and copy
MyRandom *r = new MyRandom();
myMsg1->nonce = r->getNewRandom();
this->na = myMsg1->nonce;

// copy name and length
myMsg1->name = new char[nameMsg1.size()];
strcpy(myMsg1->name, nameMsg1.c_str());
myMsg1->length = nameMsg1.size();
}

void Client::sendMsg1()
{
// set the size of data
udp->data = new uint8_t[sizeof(myMsg1) - 1 + myMsg1->length];
int pos = 0;

memcpy(udp->data, &myMsg1->tag, sizeof(myMsg1->tag));
memcpy(udp->data + (pos += sizeof(myMsg1->tag)), &myMsg1->nonce, sizeof(myMsg1->nonce));
memcpy(udp->data + (pos += sizeof(myMsg1->nonce)), &myMsg1->length, sizeof(myMsg1->length));
memcpy(udp->data + (pos += sizeof(myMsg1->length)), myMsg1->name, myMsg1->length);

udp->write(client);
}

/* Client.h */
#ifndef CLIENT_H_
#define CLIENT_H_

#include <cstdint>  // int32_t
#include <gmp.h>
#include <iostream> // cout, endl
#include <string>   // string
#include <stdlib.h>

#include "Random.h"#include "messages.h"#include "UDP.h"
using std::cout;
using std::endl;
using std::string;

class Client
{
public:
Client();
void start();

void prepareMsg1();
void sendMsg1();string nameMsg1 = "Alice";

Msg1 *myMsg1 = new Msg1();
UDP *udp = new UDP();
};

#endif /* CLIENT_H_ */

/* UDP.cpp */#include "UDP.h"
void die(char *s)
{
perror(s);
exit(1);
}

UDP::UDP(){}

void UDP::listen()
{
data = new uint8_t[BUFLEN];
struct sockaddr_in si_me, si_other;

int s = sizeof(si_other), recv_len;
socklen_t slen = sizeof(si_other);

// create UDP socket
if ((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
die("socket");

// zero out the structure
memset((char *) &si_me, 0, sizeof(si_me));

si_me.sin_family = AF_INET;
si_me.sin_port = htons(PORT);
si_me.sin_addr.s_addr = htonl(INADDR_ANY);

// bind socket to port
if (bind(s, (struct sockaddr*) &si_me, sizeof(si_me)) == -1)
die("bind");

fflush(stdout);

if ((recv_len = recvfrom(s, data, BUFLEN, 0, (struct sockaddr *) &si_other, &slen)) == -1)
die("recvfrom()");
close(s);
}

void UDP::write(Device d)
{
struct sockaddr_in si_other;
int s = sizeof(si_other);
socklen_t slen = sizeof(si_other);

memset((char *) &si_other, 0, sizeof(si_other));

if ((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
die("socket");

si_other.sin_family = AF_INET;
si_other.sin_port = htons(PORT);

if(d == client)
{
if (inet_aton(SERVER, &si_other.sin_addr) == 0)
{
fprintf(stderr, "inet_aton() failed\n");
exit(1);
}
}
else if(d == server)
{
if (inet_aton(CLIENT, &si_other.sin_addr) == 0)
{
fprintf(stderr, "inet_aton() failed\n");
exit(1);
}
}

if (sendto(s, data, sizeof(data), 0, (struct sockaddr *) &si_other, slen) == -1)
die("sendto()");

close(s);
}

/* UDP.h */

#ifndef UDP_H_
#define UDP_H_

#include <iostream> // cout, endl
#include <stdio.h>  // printf
#include <string.h> // memset
#include <stdlib.h> // exit(0);
#include <unistd.h> // close
#include <arpa/inet.h>
#include <sys/socket.h>

#include "messages.h"
#define BUFLEN 512
#define PORT 8888
#define CLIENT "192.168.2.106"#define SERVER "192.168.2.104"
using std::cout;
using std::endl;

class UDP
{
public:
UDP();

void listen();
void write(Device);

bool output = true;
uint8_t *data = new uint8_t[BUFLEN];
};

#endif /* UDP_H_ */

/* Server.cpp */
#include "Server.h"
Server::Server(){}

Server::~Server(){}

void Server::start()
{
udp->listen();
this->printMsg1();
}

void Server::printMsg1()
{
int pos = 0;

memcpy(&myMsg1->tag, udp->data, sizeof(myMsg1->tag));
memcpy(&myMsg1->nonce, udp->data + (pos += sizeof(myMsg1->tag)), sizeof(myMsg1->nonce));
memcpy(&myMsg1->length, udp->data + (pos += sizeof(myMsg1->nonce)), sizeof(myMsg1->length));

myMsg1->name = new char[myMsg1->length];
memcpy(myMsg1->name, udp->data + (pos += myMsg1->length), myMsg1->length);

if(output)
{
cout << sizeof(myMsg1->tag)    << " Byte: TAG :    " << (int8_t) myMsg1->tag
<< endl;
cout << sizeof(myMsg1->nonce)  << " Byte: NONCE :  " << myMsg1->nonce
<< endl;
cout << sizeof(myMsg1->length) << " Byte: LENGTH : " << myMsg1->length
<< endl;
cout << sizeof(myMsg1->name)   << " Byte: NAME :   ";

for(int i = 0; i<myMsg1->length; i++)
cout << myMsg1->name[i];
}
}

/* Server.h */

#ifndef SERVER_H_
#define SERVER_H_

#include <cstdint>  // int32_t
#include <gmp.h>
#include <iostream> // cout, endl
#include <string>   // string
#include <stdlib.h>

#include "Random.h"#include "messages.h"#include "UDP.h"
using std::cout;
using std::endl;
using std::string;

class Server
{
public:
Server();
virtual ~Server();
void start();

void printMsg1();

Msg1 *myMsg1 = new Msg1();
UDP *udp = new UDP();
};

#endif /* SERVER_H_ */

0

Решение

Задача ещё не решена.

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

Других решений пока нет …

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