I'm trying to send the following array of characters over an udp socket 0x11 0x00 0x00 0x00 0xb6 0x00 0x00 0x00 0xc7. I cant get it fixed. The char array always terminates at the first 0x00 character.
tried string and array of char, tried '\0' '\0' and '\', '0' but nothing seems to work.
string request_soladin_meter_data_command="\x11";
// sendudppacket (Soladin_ipaddress,5007 count,request_soladin_meter_data_command);
struct sockaddr_in udpaddr;
int udpsocket = socket(AF_INET, SOCK_DGRAM, 0);
if (udpsocket == -1)
{
printf("Could not create socket");
}
udpaddr.sin_family = AF_INET;
udpaddr.sin_port =htons(5007 count);
udpaddr.sin_addr.s_addr = inet_addr(Soladin_ipaddress);
//checks connection
if (connect(udpsocket,(struct sockaddr *)&udpaddr, sizeof(udpaddr)) < 0)
{
perror("Connection error");
}
// sends message
send(udpsocket,request_soladin_meter_data_command.c_str(),request_soladin_meter_data_command.length(),0);
type here
CodePudding user response:
string request_soladin_meter_data_command="\x11";
Literal character strings, always get terminated by a \x00
byte. That's what they are, by definition.
std::string
's constructor that takes a literal const char *
as its parameter looks for this 00
byte, in order to figure out how long the string is. That's the only way to figure it out. There is no other way.
All your attempts to stuff a \x00
into the literal string are doomed to a failure. The suffering std::string
constructor in question has no idea that this is a fake trailing 00
byte, and not the real one. So it always takes everything up to the first \x00
it sees, and that's your std::string
. Enjoy it.
There are other std::string
constructors that do not take a const char *
for a parameter which can be used to construct an actual std::string
with a \x00
byte. Such as a constructor that takes iterators to the beginning and the one-past-the end sequence that defines the new string. Or, you can just construct an empty string and stuff a 0 byte into it:
string request_soladin_meter_data_command;
request_soladin_meter_data_command.push_back(0);
And now:
send(udpsocket,request_soladin_meter_data_command.c_str(),request_soladin_meter_data_command.length(),0);
this will happily see a std::string
with one byte, length()
will be 1, and there goes your happy little \x00
byte, over the socket.
CodePudding user response:
I would suggest using the string literal: https://en.cppreference.com/w/cpp/language/string_literal
If you construct a std::string out of a const char*
it will interpret it as a c string, ad use strlen
logic to find the length.
Constructing out of initializer list is also possible. see: https://en.cppreference.com/w/cpp/string/basic_string/basic_string