Sending a null terminating character over a socket in c - 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

Related

Use of string functions with manually set NUL-terminator

This might sound like a silly question, but I learned that sometimes, especially in C, there are things that seem obvious but aren't really safe or correct.
I have a char buffer that gets filled with text (no binary data is expected) via HTTP.
Now I want to process the request body and I think strstr() is exactly what I want.
However, strstr() needs both strings to be nul terminated.
Since I have no control over what the user will actually send, I decided to just terminate the "string" (buffer) at the end like this:
char buffer[1024];
// receive request
readHTTPRequest(buffer, sizeof(buffer));
// buffer contents is undetermined
buffer[sizeof(buffer) - 1] = 0; // always terminate buffer
const char *request_body = strstr(buffer, "\r\n\r\n");
if (request_body) {
size_t request_body_size = strlen(request_body);
}
Is this approach safe? Am I missing something?
This will only work if the buffer was completely filled. If not, you'll have uninitialized bytes in between what was actually read and the last byte.
A simple way to handle this is to initialize the buffer with all zeros:
char buffer[1024] = {0};
Or, if readHTTPRequest returns the number of bytes read, use that value instead as the index to write the 0 byte to.

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);

recv - filling always the first bytes

recv (sh , buff , 5000, 0 ).
Let assume, that my buff is mallocated for x bytes. How can I write the received bytes always from the beginning? I mean I wish to start with *buff and not with buff+x.
recv starts always writing the received data to the address given (*buff).
To make your code robust you should read in a loop until all data has arrived (this implies that subsequent calls should write to buff+received bytes.
See also Handling partial return from recv() TCP in C

is it possible that some network packets are with null bytes?

in network programming
usually we use recv() or recvfrom() for receiving packets
one of the argument is a string buffer,like
char buf[2000];
recv(sockfd, buf, len, 0);
I'm wondering whether there are some null bytes( 0 or \0) in a packet
if so, how to deal with this?
thanks
Sure it's possible. How to handle them depends on the communication protocol.
But remember that recv returns the number of bytes recieved, and it can be smaller than the buffer size.

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).

Resources