将结构转换为字节数组并在C ++中通过UDP发送数据时丢失数据

时间:2017-03-26 17:20:08

标签: c++ sockets udp uint

我有一个客户想要通过UDP向服务器发送消息。

我有一个消息struct:

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 个答案:

没有答案