Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/126.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 将结构转换为字节数组并在C+中通过UDP发送时发生数据丢失+;_C++_Sockets_Udp_Uint - Fatal编程技术网

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

C++ 将结构转换为字节数组并在C+中通过UDP发送时发生数据丢失+;,c++,sockets,udp,uint,C++,Sockets,Udp,Uint,我有一个客户端希望通过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: 现在我很困惑,

我有一个客户端希望通过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);
}

/*UDP.h*/
#ifndef UDP_H_
#定义UDP_H_
#包括//cout,endl
#包括//printf
#include//memset
#包括//退出(0);
#包括//关闭
#包括
#包括
#包括“messages.h”
#定义BUFLEN 512
#定义端口8888
#定义客户端“192.168.2.106”
#定义服务器“192.168.2.104”
使用std::cout;
使用std::endl;
类UDP
{
公众:
UDP();
虚心倾听();
无效写入(设备);
布尔输出=真;
uint8_t*数据=新uint8_t[BUFLEN];
};
#endif/*UDP_H_*/

/*Server.cpp*/
#包括“Server.h”
服务器::服务器(){}
服务器::~Server(){}
void服务器::start()
{
udp->listen();
这->printMsg1();
}
void服务器::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=新字符[myMsg1->length];
memcpy(myMsg1->name,udp->data+(pos+=myMsg1->length),myMsg1->length);
如果(输出)
{

cout tag)您正在使用strcpy复制的尾随NUL溢出分配的缓冲区,但这可能不是您看到的问题。如果您的客户端和服务器是不同的体系结构,您也可能存在字节排序问题。请尝试在生产代码中发布一个“请勿使用new、delete和char*-字符串”。@chrisdi added一个MVC此代码有几个内存泄漏和缓冲区溢出,并且
sizeof(data)
是错误的发送/接收字节数。@ghostgate我希望您理解100也不是正确的数字。
Client::sendMsg1()中的代码
几乎可以计算出正确的数字。我认为它最终将是
pos+myMsg1->length
(请注意,严格来说,这与您希望为
udp->data
分配的字节数相同。您现在的分配是
sizeof(myMsg1)-1+myMsg1->length
,看起来不太合适。-1代表什么?)
/* 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_ */