TCP File transfer with htonl & htons - c++

I am doing a file transfer program in c++ right now. It works but the only problem is I am using getline instead of read(). So the program seems to only do text files. I read in the file and store in in a char*[]. So I was wondering when I change it to read() in binary and want to send it through the sockets, do I need to do a conversion(htons,htonl, etc) on the char*[] before I pass it over? I read somewhere that you don't need to do that if it's a char*. Am I mistaken in how I am storing the information from the file?
to sum up:
How do I store information read in from a binary opened file?
If it is stored in a char*[], do I need to use htons... on it, and how?
how many bytes would I send over the sockets at a time?
Thanks very much for your any help everyone!

No, you do not need to convert the file data, send/read it as-is.
What you should do, however, is assign the file size to a variable, convert it with htonl(), and send it before then sending the file data. Then the receiver can read the file size, convert it with ntohl(), and know how many bytes to read for the file data so it knows when to stop reading and whether the full file was received or not.

Related

C++: Saving a large binary file (2GB to 4GB) to RAM in a char*?

I am working on a file transfer program in C++ which converts a file to binary, saves the bytes in a char*, then sends that char* through a TCP connection to another computer. The other computer then recreates the file locally. The program does work, but I run into a big problem with large files! I cannot allocate enough array indexes to contain the bytes! For example, if I want to send a 600MB file, I need a char* with 600 MILLION indexes. This works. But once I go any higher, the program simply cannot allocate the memory and I get errors.
A friend of mine suggested that I split the file into chunks and do the transfer chunk by chunk, however this creates a plethora of other challenges and would require me to basically rewrite the entire program.
Is there any way to get around this?
A friend of mine suggested that I split the file into chunks and do the transfer chunk by chunk, however this creates a plethora of other challenges and would require me to basically rewrite the entire program.
This is why it's called computer science, and why once you have mastered these challenges, you can head to the city and earn the big bucks.
I don't know what you mean with converting to binary, but you shouldn't have to allocate 600MB+ of memory, but work with buffering instead.
For example, to send a file from disk:
open file
read part of file in buffer
send buffer over TCP connection (repeat until done)
You could also use memory mapping (or TransmitFile() in Windows).
In case your data needs to be converted:
open file
read part in buffer
convert buffer
send buffer (repeat)

Sending a file via qextserialport

I'm using the qextserialport classes in Qt to implement serial transmissions between devices. Now, I'm required to send a file between devices connected via USB using the serialport. I have used the serialport for various functions in the past weeks but I have no idea where to start implementing this. I thought about reading data event-driven until there is no more data to read, determine the size (number of bytes) of the file before hand and send it together with the data so that it would be clear if data went missing. I also have a correct function that calculates the CCIITT 16 bit checksum so I can use that for checking as well. My question therefore is:
Can someone please send me a link to a site that could help solve my problem and explain to me what would be the most simple and effective way to send a file and receive a file via the qextserialport class in Qt. ANY help would be awsum!
You need a protocol. Simple one could be:
send length of file name as raw binary number, for example 2 bytes in network byte order
(max name length 65535 bytes)
send that many bytes of file name, encoded with UTF-8
send file size as raw binary number, for example 4 bytes in network byte order (max file size 4 gigs)
send that many bytes of file contents
You might want to add info like file date, and checksum. More advanced would be to split file to chunks, so if there is transmission error, you don't have to re-send everything. Etc.
Also, study protocols like Kermit, xmodem, zmodem to see how it's been done in the modem and BBS era. Maybe use an existing protocol like that instead of creating your own.
Note: while you could use QDataStream, it requires reliable channel, so it's not as easy as it may seem at first (requires extra buffering).

Read from an open file

I'm working on a project that encrypts data at rest, then the encrypted data is decrypted into a temporary file in order to write the unencrypted data to an XML stream. The encryption and decryption work, but I am having trouble reading the data from the file. I believe this is due to the file still being open, but I can't close the file since it gets deleted on close. I'm wondering if there's a way to read from this file?
As a last resort I could rewrite the code to just use a large encrypted buffer instead of a file, but I'd like to figure out how to read the data from the open file.
EDIT: I should've said earlier that I have the decryption logic in a C++ class and that I port the functions I need to C with extern "C". The function doing the decryption is in C++, which allowed me to get a HANDLE from the file descriptor and then use FlushFileBuffers(HANDLE) to flush the buffer.
Input and output can be buffered both at the C library level and at the kernel level; writes from one process are not necessarily immediately visible to another process until the buffer has been flushed. If you're using the C library's standard IO features, you can use fflush in the writer process to make sure its output is available to the reader process.

How to move a file in C++ after reading it via send?

Well, I've see this question about my problem and the solution seems to be good.
Send and Receive a file in socket programming in Linux with C/C++ (GCC/G++)
Well. My goal is to receive a txt file and after receiving it, I want to store it into a path.
I have now a question:
when I receive the bytes through the recv function, how can I merge all bytes into a txt file?
I think std::ofstream is what you are looking for.

Tips / Examples on sending an Image file (jpeg, png) over socket programming?

I've heard that we can somehow send an image file with binary over a socket...
But I have no idea on how to convert an image file into binary or how to even think of sending it over a socket...
Was hoping if someone could post a simple example? or point me in the right direction :) I am also using QT for just my gui, but not using QT socket programming.
Thanks so much :D I really appreciate it
Question # djc:
How would you get the directory path for an image, and somehow use the send command on that image? I'm basically using C++. But this is also a question I've had for awhile.
Any image files you have are already binary. You can just send them over the socket.
You will need to know, or have the user tell you, a path that will find the image file.
Once you have that, then you logically open the file, read it into a buffer, and then write that buffer over the socket, and finally close the file (always close what you open and free what you allocate). However, there are details to be sorted - like how does the receiving end know that the data that follows is an image and how big it is (so it knows when you've sent it all). Your protocol will, presumably, define a bit pattern (one or two bytes) that identifies the message as an image, and then probably use four bytes to specify the size of the image, followed by the correct number of bytes. You can find the size of a file using the POSIX-based stat() system call. Alternatively, you can send a series of packets containing parts of the image (again with a type - this time, of type 'image packet' instead of 'image') plus the length of the packet (which might only be a 16-bit unsigned integer, for a maximum size of 65535 bytes), plus an 'end image packet' for the last segment. This is perhaps easier for the sender; it is easy for the receiver if the data goes direct to file, but messy if the receiver needs the image in memory.