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
Related
I use custom code to create SSL connection over native Berkeley sockets interface. I need to wrap the resulted socket with iostream to use existing algorithms written in C++ with these sockets data.
Is there any easy way to do it without need to implement stream and streambuf from scratch?
I learned boost::iostreams and boost::asio.
I didn't find any way to wrap existing OpenSSL session with boost::asio. Or may be anyone knows how to do that?
After boost:asio I concentrated my research on boost:iostreams.
boost::iostreams looks like good idea, however, its problem is that it uses read buffering. So, if we need to read just 1 byte from SSL session, it asks the TCP device to read 4 kilobytes and results in timeout. From the other hand, when I set buffer size to 0, boost::iostreams start to call write method for each byte, so when I try to write 10 bytes to stream, it calls SSL_write 10 times. TCP device itself can not use write buffering, because there are no way to forward flush method to device, so application level protocol may expect that data is sent to another peer while the data remains in output buffer.
So, we need unbuffered read and buffered flushable write; is that possible with boost::iostreams?
I found solution myself.
First of all, it is required to mark the device as flushable. Because there are not ready-made template for such device, you have to inherit device<dual_use, Ch> and override its category with multiple inheritance:
struct category : device<dual_use, Ch>::category, flushable_tag
Now when you will call flush on stream, it will forward the call to your device.
Next step is to disable stream own buffering (i. e. call open with 2nd and 3rd parameters equal to 0).
In such configuration boost will write to device each byte of data separatelly. However, you can implement buffering on device level, and flush the buffer on flush call.
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.
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.
I am a newbie of network programming and I've hear about epoll. I read a couple of tutorials and now I got some basic idea of what epoll does and how I can implement this.
The question is that can I use epoll even if client will using udp connection? All the tutorials I read used tcp connection.
Also is there a good tutorials or a sample code that explains multi-thread based server implementation using epoll? Those tutorials I got from online only showed how to create a simple echo server on single thread.
Thanks in advance.
There is no problem to use epoll with UDP, the epoll just notifies if there is any data to read in the file descriptor. There are some implications in the read/write... operations related to the UDP socket behaviour (from the man page of epoll):
For stream-oriented files (e.g., pipe, FIFO, stream socket), the condition
that the read/write I/O space is exhausted can also be detected by
checking the amount of data read from / written to the target file
descriptor. For example, if you call read(2) by asking to read a certain
amount of data and read(2) returns a lower number of bytes, you can be
sure of having exhausted the read I/O space for the file descriptor. The
same is true when writing using write(2). (Avoid this latter technique if
you cannot guarantee that the monitored file descriptor always refers to a
stream-oriented file.)
On the other hand is not very usual to use the epoll directly. The best way of using epoll is using an event loop library, libev, or libevent, for example. This is a better aproach, beacause epoll is not available in every system and using this kind of libraries your programs are more portable.
Here you can found an example of libev use with UDP, and Here other example with libevent.
I know it can be used to send/receive structured object from file,
but can it be used to send/receive sequences of structured object from a socket?
http://code.google.com/p/protobuf/
Protocol Buffers is a structured data serialization (and de-serialization) framework. It is only concerned with encoding a selection of pre-defined data types into a data stream. What you do with that stream is up to you. To quote the wiki:
If you want to write multiple messages
to a single file or stream, it is up
to you to keep track of where one
message ends and the next begins. The
Protocol Buffer wire format is not
self-delimiting, so protocol buffer
parsers cannot determine where a
message ends on their own. The easiest
way to solve this problem is to write
the size of each message before you
write the message itself. When you
read the messages back in, you read
the size, then read the bytes into a
separate buffer, then parse from that
buffer.
So yes, you could use it to send/receive multiple objects via a socket but you have to do some extra work to differentiate each object stream.
I'm not familiar with protobuf, but the documentation says you can create a FileInputStream (which can then be used to create a CodedInputStream) using a file descriptor. If you're on a system that supports BSD sockets, you should presumably be able to give it a socket file descriptor rather than an ordinary one.
Protocol Buffers does not handle any surrounding network/file I/O operations. You might want to consider using Thrift, which includes socket communication libraries and server libraries with the serialization/deserialization.