DBUS-libdbus string size changes - dbus

I am using libdbus-1 for IPC.
I have observed that there is an unexpected behavior when I use DBUS_TYPE_STRING.
Sending side:
str.size() is 20
dbus_message_iter_append_basic (&argsIter, DBUS_TYPE_STRING, &str);
Receiver side:
dbus_message_iter_get_basic(&argsIter, &str)
str.size() becomes 449
However content of the string I can print with [%s] specifier and it is same at sender and receiver.
If I increase the size of string at sender to be more than 449 the receiver side size becomes aroun 820~
Is it normal behaviour ?
I was expecting size to be same at sender and receiver.
thanks n regards
tanweer

I think that you're passing the wrong type to dbus_message_iter_get_basic. That will crash the application eventually.
Docs have an example with something like that:
DBusBasicValue value;
dbus_message_iter_get_basic(&read_iter, &value);
Then, to get a std::string from it, use value.str which is of type char*.

Related

Printing a bitstream data /TCP related

I am trying to make a communication between a Client and a Sever through TCP.
Let's say the client send 10 Hex numbers as bitstream to Sever. send(socketID, pSend, 20, 0); Where pSend = &ArrayClient; and unsigned short ArrayClient[] = { 0A, 0B, BA, B1...., FA }.
The sever receive the bytes stream with recv(acceptID, pRecv, 20, 0). How can I print out the content in my pointer pRecv correctly. As Sever I won't know how many bytes did the Client send, therefore I don't know how many to print.
Because the datas were sent as bitstream, not a string. I can not know the end of the message by finding \0 like working with string.
So is there a way that I can know how many bytes that I received as sever, or any way to print out the bitstream in my pRecv as Hex numbers.
I have tried pointer to a pointer and something similar like this:
while( ((unsigned int*)pRecv)[i] != 0){
printf("%X", ((unsigned int*)pRecv)[i]);
i++;
}
When dealing with TCP, there is no built-in way of separating messages, so your protocol needs to delimit the message boundaries in some known way.
A simple way of doing this is by first sending single byte denoting the length of the message, then sending that number of bytes.
For example, before sending the above message, do this:
char mlen = 20;
send(socketID, &mlen, 1, 0);

Sending a null terminating character over a socket in c

I'm trying to send a string with a null terminating character inside of it to another connection.
Now I'm not dumb, I know a string will stop at that character, but is there any possible way to send a string to a socket like this, "Test\x00AFTERNULL\x00\r\n".
I was thinking maybe there's a way to convert it from one encoding to another or something. I'm not exactly smart in this area. Thanks for any help/input.
Sending over socket is not related to having null in middle of string or not, because send() will send a buffer with specific size.
This buffer can have any amount of zeroes in middle of it. You probably have used strlen() to get size of string and used it in send() which result in incorrect buffer length and missing some part of data.
You can do it like this for example (very simple one):
char buf[] = "Test\0AFTERNULL\0\r\n";
//'s' is socket descriptor
send(s, buf, sizeof(buf), 0);
Send and receive data via socket use byte array, not string.
Exampe: create array: {'T', 'E', 'S','T', 0, 'A'}, send this via socket with leng is 6. And the other socket will received same array

C Socket Write adding extra characters

I am trying to append " " to messages in a chat program. In the below example buf is a character array holding the message. The weird thing is when I send this down a socket with write() it sends it in 2 bursts. The first burst is the correct message, then a second burst is 2-3 random non alphabetic ascii characters. Any idea what is up? When I just send buf down the socket, it works correctly.
char nickmsg[550];
strcpy(nickmsg, "<");
strcat(nickmsg, username);
strcat(nickmsg, "> ");
strcat(nickmsg, buf);
write(sd, nickmsg, sizeof(nickmsg));
You don't want sizeof(nickmsg), you want strlen(nickmsg). Using sizeof(nickmsg), you're sending everything that's in that buffer, not just the string you built in it. If it's only the chars in the string you want to send, you need to calculate the length of what's in there. (btw, there are more efficient ways to create strings than repeated strcats)
You have this code:
char nickmsg[550];
strcpy(nickmsg, "<");
strcat(nickmsg, username);
strcat(nickmsg, "> ");
strcat(nickmsg, buf);
write(sd, nickmsg, sizeof(nickmsg));
This always sends 550 bytes, since sizeof(nickmsg) is 550. The end of the message will be marked by a zero-byte because nicknmsg is a C-style string.
If the receiver always grabs 550 bytes and ignores all bytes after the zero, this will work fine. You'll just be sending some junk bytes to the clients which might leak sensitive information.
The question is, what are you supposed to be sending? What is supposed to mark the end of the message?
Caution: Do not change sizeof(nickmsg) to strlen(nickmsg). That will leave the client no way at all to identify the end of the message. (Unless you are 100% positive the client does not need to identify the ends of messages.)
write() isn't sending extra characters, you are.
write(sd, nickmsg, sizeof(nickmsg));
Will send 500 characters (the size of your array). Since you didn't initialize all array elements to 0 you're getting whatever garbage is in memory past the data you inserted into it.
You want:
write(sd, nickmsg, strlen(nickmsg) + 1);
You are sending 500 bytes data, within which only first strlen(username)+3 has valid data. The rest is just the uninitialized data.
If you send it this way
write(sd, nickmsg, sizeof(nickmsg));
you are sending data equivalent to size of the buffer.Though your string may be valid c string ending with null character but still the client may not be treating strings that way.(If you are writing your own client program you may cover up in the client's program).

Does a "UDP Client For the TIME Service" need to check the length of the read data before converting?

I'm in the middle of of reading Internetworking with TCP/IP Vol III, by Comer.
I am looking at a some sample code for a "TIME" client for UDP.
The code gets to the point where it does the read of the response, and it takes what should be a 4 bytes and converts it to a 32 bit unsigned integer, so it can be converted to UNIX time.
"n" is a file descriptor that points to a socket that listens for UDP.
n = read (s, (char *)&now, sizeof(now));
if (n < 0)
errexit("read failed: %s\n", strerror(errno));
now = ntohl((u_long)now); /* put in host byte order */
What I am wondering is:
Are there some assumptions that should be checked before making the conversion? This is in C, and I am wondering if there are situations where read would pass a number of bytes that is not 4. If so, it seems like "now" would be a mess.
"Now" is defined as:
time_t now; /* 32-bit integer to hold time */
So maybe I don't understand the nature of "time_t", or how the bytes are passed around in C, or what situations UDP would return the wrong number of bytes to the file descriptor...
Thanks in advance.
With UDP, as long as the recieve buffer you pass to read is long enough, a single UDP packet won't be broken up between read calls.
However, there's no guarantee that the other side sent a packet of at least 4 bytes - you're quite right, if a server sent only a 2 byte response then that code would leave now containing garbage.
That probably doesn't matter too much in this precise situation - after all, the server is just as free to send 4 bytes of garbage as it is to send only 2 bytes. If you want to check for it, just check that the n returned by read is as long as you were expecting.

How do I send an array of integers over TCP in C?

I'm lead to believe that write() can only send data buffers of byte (i.e. signed char), so how do I send an array of long integers using the C write() function in the sys/socket.h library?
Obviously I can't just cast or convert long to char, as any numbers over 127 would be malformed.
I took a look at the question, how to decompose integer array to a byte array (pixel codings), but couldn't understand it - please could someone dumb it down a little if this is what I'm looking for?
Follow up question:
Why do I get weird results when reading an array of integers from a TCP socket?
the prototype for write is:
ssize_t write(int fd, const void *buf, size_t count);
so while it writes in units of bytes, it can take a pointer of any type. Passing an int* will be no problem at all.
EDIT:
I would however, recomend that you also send the amount of integers you plan to send first so the reciever knows how much to read. Something like this (error checking omitted for brevity):
int x[10] = { ... };
int count = 10;
write(sock, &count, sizeof(count));
write(sock, x, sizeof(x));
NOTE: if the array is from dynamic memory (like you malloced it), you cannot use sizeof on it. In this case count would be equal to: sizeof(int) * element_count
EDIT:
As Brian Mitchell noted, you will likely need to be careful of endian issues as well. This is the case when sending any multibyte value (as in the count I recommended as well as each element of the array). This is done with the: htons/htonl and ntohs/ntohl functions.
Write can do what you want it to, but there's some things to be aware of:
1: You may get a partial write that's not on an int boundary, so you have to be prepared to handle that situation
2: If the code needs to be portable, you should convert your array to a specific endianess, or encode the endianess in the message.
The simplest way to send a single int (assuming 4-byte ints) is :
int tmp = htonl(myInt);
write(socket, &tmp, 4);
where htonl is a function that converts the int to network byte order. (Similarly,. when you read from the socket, the function ntohl can be used to convert back to host byte order.)
For an array of ints, you would first want to send the count of array members as an int (in network byte order), then send the int values.
Yes, you can just cast a pointer to your buffer to a pointer to char, and call write() with that. Casting a pointer to a different type in C doesn't affect the contents of the memory being pointed to -- all it does is indicate the programmer's intention that the contents of memory at that address be interpreted in a different way.
Just make sure that you supply write() with the correct size in bytes of your array -- that would be the number of elements times sizeof (long) in your case.
It would be better to have serialize/de-serialize functionality in your client /server program.
Whenever you want to send data, serialize the data into a byte buffer and send it over TCP with byte count.
When receiving data, de-serialize the data from buffer to your own interpretation .
You can interpret byte buffer in any form as you like. It can contain basic data type, objects etc.
Just make sure to take care of endianess and also alignment stuff.
Declare a character array. In each location of the array, store integer numbers, not characters.
Then you just send that.
For example:
char tcp[100];
tcp[0] = 0;
tcp[1] = 0xA;
tcp[2] = 0xB;
tcp[3] = 0xC;
.
.
// Send the character array
write(sock, tcp, sizeof(tcp));
I think what you need to come up with here is a protocol.
Suppose your integer array is:
100, 99, 98, 97
Instead of writing the ints directly to the buffer, I would "serialize" the array by turning it into a string representation. The string might be:
"100,99,98,97"
That's what would be sent over the wire. On the receiving end, you'd split the string by the commas and build the array back up.
This is more standardised, is human readable, and means people don't have to think about hi/lo byte orders and other silly things.
// Sarcasm
If you were working in .NET or Java, you'd probably encode it in XML, like this:
<ArrayOfInt><Int>100</Int><Int>99</Int><Int>98</Int><Int>97</Int></ArrayOfInt>
:)

Resources