Home > Net >  Sending \0 character over UDP c
Sending \0 character over UDP c

Time:01-30

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

  • Related