How to properly catch the initial response of a server? - c++

My C++ program is trying to check status of a ftp-server. It uses winsock and simple testing function that looks like this (pseudocode):
create a tcp socket
connect to port 21 of the server
do recv() while data is available
close socket
return received data
It doesn't send any data to the server with send() - just trying to catch server's initial response. This actually works and returns "200 Response Server Ready" - it is exactly what I need. But after 2nd run of the same function (immediately after 1st run) it returns nothing (because recv() returns -1). Wireshark tells me the server really didn't send a response. After that I placed a half-second pause between the testing function calls and now it works, but this solution is unwanted.
The question is: How to properly catch the server's (not only ftp, but any other too) initial response?

I think you don't need to catch answer of server. If your program connects to some port, then some server listening to this port and is OK. So just open connection and check socket variable.
PS: A lot of servers don't do anything until you send data to them (not sure about FTP), you have to send something to get answer. But to have status succesfull connection is enough.

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.

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 to find out a TCP server's status from the client side (In a redundant server case)?

I have a situation here. I have a redundant TCP server setup which takes an input and then throws lots of packets forever. While reading them, I am also trying to keep up with the server's state from TCP client by doing a send on the socket.
But my servers are redundant sharing a Virtual IP. So if server1 goes down, server2 starts up and uses the same VIP (At all point of time VIP is up and running). So my send technique is able to find out this situation.
My server2 waits for the client's input, but since send is not doing the job I expect it to do, I am not able to send the input again.
int status = ::send ( m_sock, s.c_str(), s.size(), MSG_NOSIGNAL );
if ( status == -1 )
{
return false;
}
else
{
return true;
}
Can someone help how I can figure out this kind of failover?
Okay, piecing things together, I am starting to get a picture here.
The OP is using some kind of failover in which the remote server doesn't actually keep track of the state
The reason you're not getting EPIPE from the send is that things happen this way:
You send data. send unblocks and segments start travelling
The remote server receives data. "Who is this guy ? RST!"
You get the RST but send has already returned. The connection is torn but there is no way to inform you of it (it doesn't have any out-of-band mechanism)
Do another send
In conclusion, if you want to test if a connection is still alive:
send data
Wait a bit (RTT and such)
send again
If you don't get EPIPE after the second send, the connection is still up. Another scheme:
send data that should be interpreted as "Say something if you're alive!"
Wait a bit
If after the timeout you haven't received confirmation, the connection is dead
A TCP session cannot be failed over from one server to another simply by the second server taking over the first's IP address - the TCP session state information must also be replicated from the primary server to the secondary, which requires special software.
Eventually the send to the server that has taken over must fail because that server won't know about the connection from the client IP:port, so it will issue an RST, which comes back as send() returning -1 and errno = ECONNRESET. This almost certainly won't happen on the first send after the failover because of asynchronicity and buffering.

client socket sends data but server socket does not receive them. c++ buffered stream?

I am working on a project where a partner provides a service as socket server. And I write client sockets to communicate with it. The communication is two way: I send a request to server and then receive a response from server.
The problem is that I send the data to the server but apparently the server cannot receive the data.
From my side I just use very simple implementation just like the example from http://www.linuxhowtos.org/C_C++/socket.htm
#include <sys/socket.h>
socket_connect();
construct_request_data();
send(socket, request_data, request_length, 0/*flag*/); // I set flag as 0
// now the server should receive my request and send response to me
recv(socket, response_data, response_length, 0);
socket_close();
And it seems that the server socket is implemented with a "binding" to std::iostream and it is buffered stream. (i.e. the socket send/recv is done in iostream::write/read.)
server_socket_io >> receive_data;
server_socket_io << response_data;
Btw, I got a test client from my partner and it is wrapped in a iostream as well. The test socket client can communicate with the server without problem, but it must do iostream::flush() after every socket send.
But I want to just keep it simple not to wrap my socket client in iostream.
I just wonder whether the buffered iostream results in the problem: the data is not processed since the data the client socket sent is just in very small amount and still buffered.
Or could it be my problem? how can I know if I really send out the data? does my client socket also buffer the data?
I have tried some "bad" workaround with TCP_NODELAY but it didn't help!
How can I solve the problem? from client side? or server side?
Should I close the socket after sending request and before receiving response, so that the data will be "flushed" and processed?
or should I wrap my socket in iostream and do flush?
or the server socket should use a "unbuffered" stream?
thanks for any suggestion and advice!
Further to Jay's answer, you can try any network packet sniffer and check whether your packets are getting to the server or not. Have a look at wireshark or tcpdump.
Let's use "divide and conquer" to solve the problem.
First, does the server work?
From your code look up the port number that your server is listening on.
Start your server program.
Run the following command line program to see if the server is really listening:
netstat -an -p tcp
It will produce a list of connections. You should see a connection on your selected port when the server is running. Stop the server and run the command again to ensure the port is no longer in use.
Once you've verified the server is listening try to connect to it using the following command:
telnet your-server-address-here your-port-number-here
telnet will print what your server sends to you on the screen and send what you type back to the sever.
This should give you some good clues.
I had a similar issue once before. My problem was that I never 'accepted' a connection (TCP) on the server inorder to create the stream between server/client. After I accepted the connection on the server side, everything worked as designed.
You should check the firewall settings for both systems. They may not be passing along your data.

C++ socket concurrent server

I'm writing a concurrent server that's supposed to have a communication channel and a data channel.
The client initially connects to the communication channel to authenticate, upon successful authentication, the client is then connected to the data channel to access data.
My program is already doing that, and I'm using threads. My only issue is that if I try to connect another client, I get a "cannot bind : address already in use" error.
I have it this way:
PART A
Client connects to port 4567 (and enters his login info). A thread is spawned to handle the client (repeated for each client that connects). In the thread created, I have a function (let's call it FUNC_A) that checks the client's login info (don't worry about how the check is done), if successful, the thread starts the data server (listening on 8976), then sends an OK to the client, once received the client attempts to connect to the data server.
PART B
Once a client connects to the data server, from inside FUNC_A the client is accepted and another thread is spawned to handle the client's connection to the data server (hopefully everything is clear).
Now, all that is working fine. However, if I try to connect with second client when it gets to PART B I get a "cannot bind error: address already in use". I've tried so many different ways, I've even tried spawning a thread to start the data server and accept the client and then start another thread to handle that connection. Still no luck.
Please give me a suggestion as to what I'm doing wrong, how do I go about doing this or what's the best way to implement it.
Thank you
Your problem lies in the following: "...the thread starts the data server(listening on 8976)..."
If I understand you correctly, every time a client connects, you're trying to start listening on port 8976. The problem is, however, that there can be only one socket listening on a given port. When you try to start listening on the same port again, you get that error.
Therefore, you have two options:
Have the server listen on whatever port is free (just specify 0 when binding), and send the port number to the client, so that the client can connect to it.
Start the server only once, at the beginning, and have it accept client connections.
The second option, however, has a big problem: how are you going to tell one client from another? Therefore, I recommend going with the first option.
Some food for thought: what you're describing is pretty much exactly how FTP works. And FTP servers use the first option. Not coincidentally, perhaps? ;-)