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