I want the client program (TCP) to be ready to connect to the server program whenever the server starts to accept() incoming connections (the client program should always stay running, and the server program can start or end whenever it wants). The client code looks like this:
while (1) {
//Wait for the server to accept the connection:
while (connect(socket,(sockaddr*)&addr,sizeof(addr))!=0) {cout<<WSAGetLastError()<<endl;}
//Send whatever data...
}
On the first execution of the while (1) loop, everything runs as expected; when the client is connected to the server, it sends all the data, and the the server program is ended. Then I want the client to wait again at the while (connect(...,...,...)!=0) loop until the server starts again and accept()s a connection, but it does not connect to the server and WSAGetLastError() returns 10056, indicating that the socket is already connected (why?). I heard that you cannot reconnect the client after calling closesocket() on the socket, so I tried to disconnect the client before reconnecting by adding shutdown(socket,SD_SEND) to the while (1) loop but that doesn't work either.
Is there anything I can do besides repetitively waiting for the client program to end and starting it again? Is there some way to disconnect the client from the server program such that the client can reconnect later?
There's something seriously wrong with your application logic. You don't need to reconnect a connected socket; you can't reconnect a connected socket; and you can't reconnect a socket that has been closed, unless you're exploring one of the remote corners of the Windows API.
Related
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.
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 would I go about doing this. All in single thread
Basically, a "ClientClass" needs to have 10 nonblocking sockets. A socket will connect to a server every 100ms.
For example if I have socketlist[9], socketlist[0] will try to connect, then after 100ms socketlist[1] will connect and so on.
Client will continue to try to connect until it is fully logged in. Once one socket is connected:
save that socket position and close the rest of the sockets in that list;
close other sockets.
Thank you in advance.
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.
My application connects as a client across an ethernet to a server process.
As the server is well known and will not change, UDP and TCP are both setup using
socket();
setsockopt(SO_REUSEADDR);
bind();
connect();
The connection protocol includes heartbeats sent both ways.
When I detect an error with the connection e.g. hearbeat timeout, I need to reset the connection.
Is it sufficient just to connect() to the NULL address and then re-connect() after a short pause, or should I close the socket and then reinitialise from scratch?
thanks
After a socket error you have to discard the one in hand and restart the setup with a new socket.
Winsock documentation, for example:
When a connection between sockets is
broken, the sockets should be
discarded and recreated. When a
problem develops on a connected
socket, the application must discard
and recreate the needed sockets in
order to return to a stable point.
You have to close(2) the socket and re-do everything again. Why do you bind(2) on the client?