How to send a file using IOCP? - c++

When using blocking sockets, all I had to do to send a file was to open the file and loop through it and send it in chunks.
But I find sending a file using overlapped sockets to be more challenging. I can think of the following approach to do it:
I open the file and send the first chunk, and I keep track of the
file handle and file position (I store these data somewhere in memory).
Now when I get a completion packet indicating that some data has
been sent, I retrieve the file handle and file position and send the next chunk.
I repeat step 2 until I reach the last chunk in the file, and then I
close the file.
Is this approach correct?
Note: I don't want to use TransmitFile().
Edit: I have updated my question.

If you don't want to use TransmitFile() then you can use overlapped file I/O using IOCP where the completion of a file read is used to trigger a socket write and the completion of a socket write is used to trigger a file read. You then decide how much data you want in transit and issue that many file reads and wait for EOF...

Easiest way: look up 'TransmitFile' on MSDN. This functionality is so common, (eg. serving up web pages), that there is a specific API for it.

Related

Way to check in C/C++ if a file is in use?

Is there any way to check if a file is in use in C/C++? Or do I have to ALWAYS implement a lock/semaphore to prevent simultaneous access of any file by multiple threads/processes?
If we consider Linux, and the following scenario: I want to transfer,in chunks, the contents of a file stored in device A to another device B through RS-232 communication, using a pre-defined communication framework. When the request for this transfer comes, I want to verify the file is NOT being used by any process in device A, before sending a "Ready to Transfer : OK" response, following which I will start reading and transmitting the data in chunks.
Is there a way to check file if is already in use without doing fopen/fclose on the said file?
actually
fopen();
is the best way to find this out.
Do fopen() on the receiving end, if it is successful, send the "OK to receive" message.

update a file simultaneously without locking file

Problem- Multiple processes want to update a file simultaneously.I do not want to use file locking functionality as highly loaded environment a process may block for a while which i don't want. I want something like all process send data to queue or some shared place or something else and one master process will keep on taking data from there and write to the file.So that no process will get block.
One possibility using socket programming.All the processes will send data to to single port and master keep on listening this single port and store data to file.But what if master got down for few seconds.if it happen than i may write to some file based on timestamp and than later sync.But i am putting this on hold and looking for some other solution.(No data lose)
Another possibility may be tacking lock for the particular segment of the file on which the process want to write.Basically each process will write a line.I am not sure how good it will be for high loaded system.
Please suggest some solution for this problem.
Have a 0mq instance handle the writes (as you initially proposed for the socket) and have the workers connect to it and add their writes to the queue (example in many languages).
Each process can write to own file (pid.temp) and periodically rename file (pid-0.data, pid-1.data, ...) for master process that can grab all this files.
You may not need to construct something like this. If you do not want to get processes blocked just use the LOCK_NB flag of perl flock. Periodically try to flock. If not succeeds continue the processing and the values can stored in an array. If file locked, write the data to it from the array.

pipe "address system"

Maybe I'm misunderstanding How to make a pipe in c++ thus http://linux.die.net/man/2/pipe, but how does the pipe know where to send to or receive from?
Upon a database update via an ajax page, I want that ajax program to send a message to my websocket program to update all of the other relevant users, and it's been recommended that using pipe would probably be best how 2 c++ programs call each other's class/functions on same linux box?.
Is there just one pipe and all programs read it and validate the message?
Note: I'm using fastcgi++ and websocket++ if that helps.
If you want multiple independent processes to read from the pipe, you need to use a named pipe, also known as a FIFO.
Using the mkfifo function, one process creates a file in the file system (normally in /tmp). This file can then be opened for reading or writing using the normal open system call by any other process that have access to that file.

Sending the contents of a file to a client

I am writing a C++ server side application called quote of the day. I am using the winsock2 library. I want to send the contents of a file back to the client, including newlines by using the send function. The way i tried it doesn't work. How would i go about doing this?
Reading the file and writing to the socket are 2 distinct operations. Winsock does not have an API for sending a file directly.
As for reading the file, simply make sure you open it in read binary mode if using fopen, or simply use the CreateFile, and ReadFile Win32 API and it will be binary mode by default.
Usually you will read the file in chunks (for example 10KB at a time) and then send each of those chunks over the socket by using send or WSASend. Once you are done, you can close the socket.
On the receiving side, read whatever's available on the socket until the socket is closed. As you read data into a buffer, write the amount read to a file.
Hmm... I think Win32 should have something similar to "sendfile" in Linux.
If it doesn't you still can use memory-mapping (but, don't forgot to handle files with size larger than available virtual address space). You probably will need to use blocking sockets to avoid returning to application until all data is consumed. And I think there was something with "overlapped" operation to implement async IO.
I recommend dropping winsock and instead using something more modern such as Boost.Asio:
http://www.boost.org/doc/libs/1_37_0/doc/html/boost_asio/tutorial.html
There is also an example on transmitting a file:
http://www.boost.org/doc/libs/1_37_0/doc/html/boost_asio/examples.html

Setting a timeout on ifstream in C++?

We're trying to read data from 2 usb mice connected to a linux box (this data is used for odometry/localization on a robot). So we need to continuously read from each mouse how much it moved. The problem is that when a mouse is not moving, it doesn't send any data, so the file stream from which we get the data blocks execution and therefore the program can't do the odometry calculations (which involve time measurement for speed).
Is there a way to set a timeout on the input stream (we're using ifstream in C++ and read from /dev/input/mouse), so that we're able to know when the mouse doesn't move, instead of waiting for an event to be received? Or do we need to mess up with threads (arggh...)? Any other suggestions are welcome!
Thanks in advance!
A common way to read from multiple file descriptors in linux is to use select(). I suggest starting with the manpage. The basic system flow is as follows:
1) Initialize devices
2) Obtain list of device file descriptors
3) Setup the time out
4) Call select with file descriptors and timeout as parameters - it will block until there is data on one of the file descriptors or the time out is reached
5) Determine why select returned and act accordingly (i.e. call read() on the file descriptor that has data). You may need to internally buffer the result of read until an entire data gram is obtained.
6) loop back to 4.
This can become your programs main loop. If you already have a different main loop you, can run the above without looping, but your will need to insure that the function is called frequently enough such that you do not lose data on the serial ports. You should also insure that your update rate (i.e. 1/timeout) is fast enough for your primary task.
Select can operate on any file descriptor such network sockets and anything else that exposes an interface through a file descriptor.
What you're looking for would be an asynchronous way to read from ifstream, like socket communication. The only thing that could help would be the readsome function, perhaps it returns if no data is available, but I doubt this helps.
Using threads would be the best way to handle this.
Take a look at the boost Asio library. This might help you deal with the threading suggested by schnaeder.
No, there is no such method. You'll have to wait for an event, or create a custom Timer class and wait for a timeout to repoll, or use threads.