Apache Thrift: Terminate Connection from the Server - c++

I am using thrift to provide an interface between a device and a management console. It is possible for there to be up to 4 active connections to the device at one time, and I have this working using a TThreadPool server.
The issue arises around client disconnections; If a client disconnects correctly, there is no issue, however if one does not (i.e. the client crashes out or doesn't call client->close()) then the server seems to keep that clients thread alive. This means that when the next connection attempt is made, the client hangs, as the server has used up its allocated thread pool so cannot service the new request.
I haven't been able to find any standard, public mechanism by which the server can stop, and hence free up, a clients thread if that client has not used the interface for a set time period?
Is there a standard way to facilitate this in thrift?

Set the receive/send timeout on the server socket might help. Server will close the connection on timeout.
https://github.com/apache/thrift/blob/129f332d72facda5d06f87e2b4e5e08bea0b6b44/lib/cpp/src/thrift/transport/TServerSocket.h#L103
void setSendTimeout(int sendTimeout);
void setRecvTimeout(int recvTimeout);

Related

Checking if a program is running on local network

I want to write a simple program in c++ that use tcp socket to communicate with the same program on another computer in lan.
To create the tcp socket I could make the user write the ip and the port to make the connection. But I also need to be able to autodetect in the local area network if there is any computer also running the program.
My idea was:
when the program is autodetecting for available connection in lan, it will send all ips a message via udp to a specific port, meanwhile it will also keep listening to a port waiting to eventual answer.
when the program on the other computer is opened for lan connection, it will keep listening to the a port in case another computer is trying to detect, then it will send also via udp the response messagee notifying the possibility of connection.
All the security system is another problem for which I don't need answer now.
// Client 1:
// Search for all ips in local network
// create udp socket
// send check message
// thread function listening for answers
// if device found than show to menu
// continue searching process
// Client 2 (host) :
// user enable lan connection
// create udp socket
// thread function listening for detection requests
// if request structure is right send back identification message
// continue listening for request
My question - Is there a more efficient or standard way to do something like that?
Testing whether another computer is listening on a given port is what hackers do all day to try to take over the world...
When writing a software like you describe, though, you want to specify the IP and port information. A reason to search and automatically find a device would be if you are implementing a printer, for example. In that case, as suggested by Hero, you could use broadcasting. However, in that case, you use UDP (because TCP does not support that feature).
The software on one side must have a server, which in TCP parlance means a listen() call followed by an accept() until a connection materialized.
The client on the other side can then attempt a connect(). If the connect works, then the software on the other side is up and running.
If you need both to be able to attempt a connection, then both must implement the client and server (which is doable if you use ppoll() [or the old select()] you know which event is happening and can act on it, no need for threads or fork()).
On my end, I wrote the eventdispatcher library to do all those things under the hood. I also want many computers to communicate between each others, so I have a form of RPC service I call communicatord. This service is at the same time a client and a server. It listens on a port and tries to connect to other systems. If the other system has a lower IP address, it is considered a server. Otherwise, it is viewed as a client and I disconnect after sending a GOSSIP message. That way the client (larger IP address) can in turn connect to the server. This communicator service allows all my other services to communicate without having to re-implement the communication layer between computer over and over again.

Apache Thrift server as client

I've got server running in background and a program which should display data from server. I want to somehow launch method in my program from server. So server should be a sender, but how to do it ?
There is no reason why a server can't also be a client, just implement the interfaces from both sides and you're good.
The main thing to worry about is deadlocking: if you have a single threaded program which is waiting for the reply of the server, then it will not handle the request that the server sends, so the server is stuck and will not send a reply to the program.
This can be solved by starting the server implementations on different threads and letting them not block on the client thread.
Even better is to avoid having a server send back requests before sending replies, but cascading requests (forward requests to more specialized servers) should be no problem.

How long does a winsock connection last?

I have a program in C++ using winsock that connects to a server, the user's will need to send data to this server periodically over a very long span of time(perhaps weeks without the need to reconnect).
I have found plenty of documentation on timeouts when establishing a connection, but I am trying to find out how long the connection lasts after it has been established. Does the connection last until either program is shut down? Can I connect then wait two hours to send something?
There's no explicit connection lifetime limitation (at least in TCP). The connection lasts until one of the following:
Either endpoint (application) shuts down (actually the connection may remain in half-duplex mode)
Intermediate entity decides to terminate the connection (such as firewall, NAT or etc.)
In "real-world" internet connections are usually shut down forcibly after some period of time, especially if there's no data sent. Besides of this, depending on the protocol, some servers refuse to keep the connection open for indefinite time (such as http servers).
In conclusion: there's no generic way to discover the lifetime of the connection. You're completely in the hands of the firewalls, proxies (if applicable), and the server behalf.
Sending some data periodically (such as keep-alive messages) usually help. It also helps to detect that the connection has been silently terminated.

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? ;-)

Multithreaded Server Issue

I am writing a server in linux that is supposed to serve an API.
Initially, I wanted to make it Multi-threaded on a single port, meaning that I'd have multiple threads working on various request received on a single port.
One of my friends told me that it not the way it is supposed to work. He told me that when a request is received, I first have to follow a Handshake procedure, create a thread that is listening to some other port dedicated to the request and then redirect the requested client to the new port.
Theoretically, it's very interesting but I could not find any information on how to implement the handshake and do the redirection. Can someone help?
If I'm not wrong in interpreting your responses, once I create a multithreaded server with a main thread listening to a port, and creates a new thread to handle requests, I'm essentially making it multithreaded on a single port?
Consider the scenario where I get a large number of requests every second. Isn't it true that every request on the port should now wait for the "current" request to complete? If not, how would the communication still be done: Say a browser sends a request, so the thread handling this has to first listen to the port, block it, process it, respond and then unblock it.
By this, eventhough I'm having "multithreads" , all I'm using is one single thread at a time apart from the main thread because the port is being blocked.
What your friend told you is similar to passive FTP - a client tells the server that it needs a connection, the server sends back the port number and the client creates a data connection to that port.
But all you wanted to do is a multithreaded server. All you need is one server socket listening and accepting connections on a given port. As soon as the automatic TCP handshake is finished, you'll get a new socket from the accept function - that socket will be used for communication with the client that has just connected. So now you only have to create a new thread, passing that client socket to the thread function. In your server thread, you will then call accept again in order to accept another connection.
TCP/IP does the handshake, if you can't think of any reason to do a handshake than your application does not demand it.
An example of an application specific handshake could be for user authentication.
What your colleague is suggesting sounds like the way FTP works. This is not a good thing to do -- the internet these days is more or less used for protocols which use a single port, and having a command port is bad. One of the reasons is because statefull firewalls aren't designed for multi-port applications; they have to be extended for each individual application that does things this way.
Look at ASIO's tutorial on async TCP. There one part accept connections on TCP and spawns handlers that each communicate with a single client. That's how TCP-servers usually work (including HTTP/web, the most common tcp protocol.)
You may disregard the asynchronous stuff of ASIO if you're set on creating a thread per connection. It doesn't apply to your question. (Going fully async and have one worker-thread per core is nice, but it might not integrate well with the rest of your environment.)