How to keep connection alive between two process - c++

I try to keep the connection between the two consoles alive even after a connection has been made between them. I use Microsoft libraries- Pipe.
Once the Server and the Client are connected they are automatically disconnected.
Is it possible to keep the connection alive for a few minutes?
My goal is to transfer information between the client and the server and return the information after changes have been made by the server.
https://learn.microsoft.com/en-us/windows/win32/ipc/multithreaded-pipe-server
https://learn.microsoft.com/en-us/windows/win32/ipc/named-pipe-client

In Microsoft's sample code for a named pipe server (for which you provided the link), the server simply calls ReadFile once to obtain a message, then processes the message and generates a response text using GetAnswerToRequest, and then sends that response using WriteFile. Afterwards, it gracefully closes the pipe by calling:
FlushFileBuffers(hPipe);
DisconnectNamedPipe(hPipe);
CloseHandle(hPipe);
When the client has finished reading the reply message from the server, it is programmed to print the following line and to exit afterwards:
printf("\n<End of message, press ENTER to terminate connection and exit>");
In your question, you wrote the following:
Once the Server and the Client connected they are automatically disconnected.
This statement is not quite correct. As stated above, the client is programmed to exit as soon as it has finished receiving the reply from the server.
If you want to keep the connection alive for a longer period, then you can for example
reprogram the server to delay the sending of the response to the client, or
reprogram the server to process more than one message per client before closing the pipe, and reprogram the client to read more than one message from the pipe before exiting.

Related

boost asio notify server of disconnect

I was wondering if there is any way to notify a server if a client side application was closed. Normally, if I Ctrl+C my client side terminal an EOF-signal is sent to the server side. The server side async_read function has a handle which has boost::system::error_code ec argument fed into it. The handle is called when the server side receives EOF-signal which I can happily process and tell the server to start listening again.
However, if I try to cleanly close my client application using socket.shutdown() and socket.close() nothing happens and the server side socket remains open.
I was wondering, is there a way to somehow send an error signal to the server-side socket so I could then process it using the error code?
The approaches described in comments covers 99% of cases. It doesn't work when client machine was (not gracefully) turned off, or network problems.
To get reliable notification of disconnected client you need to implement "ping" feature: to send ping packets regularly and to check that you received pong packets.

How to use waitformultipleobject in C++

I am trying to write a code that will wait for client connections. As soon as it gets connected to a client, it should start reading a file and send it.
I need to have notifications for the socket handles, that is if connection gets lost from client side it will notify me so that I can try to reconnect.
If a connection is lost, it is up to the client side to reconnect. Servers do not connect or reconnect to clients.
If your server is simply dispensing a file, all you need to do is to accept connections and pass them to a handler that will invoke TransmitFile() at some point and clean up.
I am assuming the parts about waiting for client connections and sending a file are just for clarification and you already got that working. If not, there are lots of tutorials on sockets and file I/O out there.
In your case, detecting whether or not a client is still connected should be simple. Since your server is sending a file as soon as the connection is made, the client will start reading from the socket as soon as it is open. The read-function blocks, as long as the connection is open and no data was received. If the connection is closed, it will return having read 0 bytes. At that point you know, that the connection was terminated and you can try to reconnect.
If you are not permanently reading from the socket but keeping it open for future communication, you should look into the select-function, which allows monitoring one or more sockets and notifies you, as soon as one of them has an update (for example new data available or connection closed)

using sockets, what is the best practice to signal an end of communications?

I am writing a client-server application using sockets in C++.
The protocol for communications is essentially:
The client connects to the server.
The client "sends" an ASCII command to the server.
The server executes the command remotely, and gets the results, and sends the results back to the client.
the results can be multiple megabytes of data. Once all the results are sent to the client, I would like the server to signal the client that it's done.
Is the best way to closesocket(), or should it send a message that indicates to the client that there are no more results, and the client can decide whether to close the socket or not? The drawback with closing the socket is that the client will need to establish a new connection if it wants to execute another command, but the drawback of sending a message back from the server is that the client needs to scan every recv to determine if the results are done.
Which is the best practice?
I would take a slightly lateral approach:
Client sends command to server
Server send size of response and then the real response
Client can issue new command / close connection
In this way the client knows how much to read and can decide whether to close the connection or not.

How can I create a simple server with only 2 clients in C++?

I need to create a server that allow ONE at time client connected.
The rule is that just one client can be connected and if the other one try to connect, can read a messagge like this "another client is connected, do you want disconnect it?".
Then if type yes the client will be disconnected.
My problem is about this step. How can I disconnect a client and connect the other one?
Can someone help me?
Thank you.
First build the abstract server structure. So you write a program which accepts TCP connections in one thread and pass them to a worker thread, which can read and send messages.
You should keep one Singleton containing a reference (or pointer, your choice) to the Worker with the currently connected client (or null, if there is noone connected).
To keep it simple, the acceptor thread should create a new Worker thread everytime it accepts a connection, and the Worker thread is terminated, when the connection breaks up.
Now you have to think about a protocol. For this simple task, 5 messages should be enough. Maybe every message ends with an endl, so you can use methods like readline if there is somthing like this in C++.
First, the CONNECT message. The server should return OK (second message), if noone is connected to it, and ERROR (third message), if there is already one connected.
The fourth message is CONNECTWITHDISCONNECT, it connects the client to the server and disconnects any other client. The newly connected client should receive a OK message from the server, and the disconnected one should receive DISCONNECT (fifth message).
Now, you could use the disconnect message also with the client, so one can disconnect, without requiring another to connect.
The client should send a CONNECT first, if it receives ERROR then, it can ask the user to disconnect the other client, and if the user wants to, the client sends CONNECTWITHDISCONNECT.
Another option (if you don't want to deal with multiple threads or multiple processes) is to use select() or poll() to handle multiple sockets at the same time within a single thread. In particular, you can select()-for-read on your accepting socket, and select() will return with that socket marked as ready-for-read whenever another client is trying to connect. Once you have accept()'d the client, you can pass the client's connection socket (as was returned by accept()) to select()'s read-sockets-set so that you will also be notified whenever the client's socket has bytes ready for you to read. And so on.

How to detect client connection to a named pipe server using overlapped I/O?

I was studying the MSDN examples of using named pipes:
Named pipe server using overlapped I/O
Named pipe client
The server easily detects when the client is disconnected and creates a instance of a named pipe. But I cannot figure out how the server knows that a client is connected to a pipe before any data from client is sent.
Can server detect a connceted client before client sends any data?
If server calls DisconnectNamedPipe before client disconnects itself first, will this disconnect the client as well? Can server disconnect a client from a pipe without negotiating it with the client?
Not sure I understand the hang-up. The server calls ConnectNamedPipe to wait for a client connection. No data needs to be sent. Nor can it be sent, you cannot issue a ReadFile until a client is connected. Note that the SDK sample uses this as well.
If the server disconnects ungracefully (without notifying the client with some kind of message so it can close its end of the pipe) then the client will get an error, ERROR_PIPE_NOTCONNECTED (I think). There's little reason to rely on that for a normal shutdown, you need to do something reasonable when the pipe server process crashed and burned unexpectedly.
Beware that pipes are tricky to get right due to their asynchronous nature. Getting errors that are not actually problems is common and you'll need to deal with it. My pipe code deals with these errors:
ConnectNamedPipe: ERROR_PIPE_CONNECTED on connection race, ignore
FlushFileBuffers: race on pipe closure, ignore all errors
WaitNamedPipe: ERROR_FILE_NOT_FOUND if the timeout expired, translate to WAIT_TIMEOUT
CreateFile: ERROR_PIPE_BUSY if another client managed to grab the pipe first, repeat
Server works incorrectly when clients get ERROR_FILE_NOT_FOUND error during WaitNamedPipe() or/and CreateFile() calls. This error code means there no pipes with specified name available on server. You should create new pipe on server immediately after ConnectNamedPipe() call to avoid this issue.