У меня есть клиент, который хочет отправить сообщение на сервер через 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_ */
Задача ещё не решена.
Других решений пока нет …