I am new to openSSL and want to know about the difference in using SSL_* and BIO_* functions for reading and writing data. Also it would be great if we could have some examples telling the usecases for both.
Thanks
Ravi
SSL_* functions operate on an SSL connection. BIO_* functions stand for basic input and output which are used for reading and writing operations over different input/output devices such as file, memory buffer or even socket connection.
SSL_* function performs the required encryption/decryption of the data whereas BIO_* does not.
There are plenty of use cases for both.
For SSL_* whenever you want to make an SSL client or server, you need this.
For reading and writing from the file or memory buffer, you may need BIO_* function. Common use is some i2d_ or d2i_ functions which writes or reads to/from an input/output device. For example, you want to write your public key to a BIO_* which can be memory buffer or a file, you can open the input into BIO * structure. Your writing code will not make any distinction about file or buffer and will write over BIO *
Related
I'm connecting to a websocket using the boost/beast libraries and writing the data into a beast::flat_buffer. My issue is that I'm having trouble getting the data from buffer. I have a thread-safe channel object that I can to write to, but I'm not sure how to pull the most recently received message from the buffer.
beast::flat_buffer buffer;
// send through socket
send_socket(
ws, get_subscribe_string(trade_tickers, bar_tickers, quote_tickers));
// read into buffer
while (channel.running) {
ws.read(buffer); // need to write the most recently received message into the channel
}
I can write to the channel with channel.write(std::string arg). Any ideas on how to pull from the buffer?
The interface for flat_buffer is documented here: https://www.boost.org/doc/libs/1_77_0/libs/beast/doc/html/beast/ref/boost__beast__flat_buffer.html
As you can see it is a rich interface that lends itself to a number of different usage patterns, including reading and writing blocks in FIFO style.
Now, if you are using websockets, your protocol is already message-oriented rather than stream oriented. You might just want to access all of the data as one "body". In my opinion, the safe, expressive and flexible way to do this is using the data() member. This models the general Asio Buffer concept meaning that you can use the Buffer Iterators on it, without worrying about any of the buffer implementation details:
std::string text(buffers_begin(buffer), buffers_end(buffer));
For an example of this in actual use (to receive JSON or msgpack) see this recent answer: I would like to parse a boost::beast::flat_buffer with msgpack data using nlohmann:json
Think Outside The Box
Note the implication though: The flat_buffer is not mandatory. In fact, it's just one (simple) implementation modeling the DynamicBuffer concept.
You could use any model, so instead you can receive directly into a string:
std::string str;
auto buf = boost::asio::dynamic_buffer(str);
ws.read(str);
If you reuse str instance, e.g. just using str.clear() it may not be bad in terms of allocations.
I'm using the standard C/C++ socket function, but I'd like to encapsulate them into a C++ class. The problem is that the functions for sending and receive returns (or require) pointers to void. Is there any way to use an object that encapsulates those values?
For example, in Java the Socket class uses both ObjectOutputStream and ObjectInputStream in order to work with Object type so every object can be sent via Sockets.
I know that in Java the approach is quite different because the pointers are hidden to the programmer, but is there any similar solution in C++?
socket isn't a c++ function. It's a system level function and it doesn't know anything about objects (or indeed anything in c++), so you have to arrange to provide it with a pointer to the data you want transferred.
As #GCT says, socket isn't a function but is a system level function which is used to handle network connections. In C/C++ each socket is identified with an Integer value, so it's not easy, as you want, to handle it as an object.
I recommend you to read this tutorial to know more about socket.
Maybe it can help you: I have a project that show how to use sockets in C++. Server and client are contained in their own class. You can get it by this link.
I have a C++ Node.js extension that does network communication. Currently, it creates its own TCP connections in C. I would like to have it use sockets created in Node to take advantage of standard libraries like Cluster and to be able to use the existing event loop.
The solution I see is to simply create a net.Socket object and then extract the uv_tcp_t value from the underlying TCPWrap object. There are a couple of issues I see with this option:
The Socket documentation seems to indicate that a socket immediately starts reading when it connects. I would expect that to cause data loss if I want to read on the underlying UV socket in the extension instead of listening for the 'data' event in JavaScript.
While the TCPWrap class has a function to get the underlying uv_tcp_t struct, it does not seem to have an API to relinquish ownership of that struct. I expect this to cause problems later related to disposing of the struct and ownership of its data member (used for user data).
Is there any way to avoid these issues and use the socket in the extension?
In C++, I know I can use read or write file using system function like read or write and I can also do that with fstream's help.
Now I'm implementing a disk management which is a component of DBMS. For simplicity I only use disk management to manage the space of a Unix file.
All I know is fstream wrap system function like read or write and provide some buffer.
However I was wondering whether this will affect atomicity and synchronization or not?
My question is which way should I use and why?
No. Particularly not with Unix. A DBM is going to want contiguous files. That means either a unix variant that support them or creating a disk partition.
You're also going to want to handle the buffering; not following the C++ library's buffering.
I could go on but streams are for - - streams of data -- not secure, reliable structured data.
The following information about synchronization and thread safety of 'fstream' can be found from ISO C++ standard.
27.2.3 Thread safety [iostreams.threadsafety]
Concurrent access to a stream object (27.8, 27.9), stream buffer
object (27.6), or C Library stream (27.9.2) by multiple threads may
result in a data race (1.10) unless otherwise specified (27.4). [
Note: Data races result in undefined behavior (1.10). —end note ]
If one thread makes a library call a that writes a value to a stream
and, as a result, another thread reads this value from the stream
through a library call b such that this does not result in a data
race, then a’s write synchronizes with b’s read.
C/C++ file I/O operation are not thread safe by default. So if you are planning to use fstream of open/write/read system call, then you would have to use synchronization mechanism by yourself in your implementation. You may use 'std::mutex' mechanism provided in new C++ standard(.i.e C++11) to synchronize your file I/O.
I can see it looks like an alias for an unsigned int pointer, right? Is it just like a pointer in memory? To what would it be actually pointing? Is it pointing to a struct? If yes, how is that struct defined? Is it just a number that is used by socket functions and does not map to a memory address?
In Win32, a SOCKET data type is the same as a HANDLE, which is an integer used to refer to a kernel data structure of some kind. This kernel data structure is "opaque", which means that application programs do not need to (and in fact cannot) see the internals of the structure. All access to Win32 SOCKETs is done through Winsock API functions.
Note that in Win16, a SOCKET was not the same thing because there was no Win16 HANDLE type. However, Win32 kept the same type name for source compatibility.
from wikipedia-
Generally, a file descriptor is an
index for an entry in a
kernel-resident data structure
containing the details of all open
files. In POSIX this data structure is
called a file descriptor table, and
each process has its own file
descriptor table. The user application
passes the abstract key to the kernel
through a system call, and the kernel
will access the file on behalf of the
application, based on the key. The
application itself cannot read or
write the file descriptor table
directly.
link
You could check out the Linux source for socket.h, for instance. Although in the case of sockets (the type of which is not actually described in socket.h), a socket is a file descriptor, not unlike the return of open in C (which you don't use in day-to-day programming).
As to what is a file descriptor: at a very high level, it's typically just an int that the OS translates into a way to communicate with a file object, or a socket object for network communications, or a pipe to communicate between processes...