views:

93

answers:

5

I have a rather tricky problem regarding C++ program flow using sockets.

Basically what I have is this: a simple command-line socket server program that listens on a socket and accepts one connection at a time. When that connection is lost it opens up for further connections.

That socket communication system is contained in a class. The class is fully capable of receiving the connections and mirroring the data received to the client. However, the class uses UNIX sockets, which are not object-oriented.

My problem is that in my main() function, I have one line - the one that creates an instance of that object. The object then initializes and waits. But as soon as a connection is gained, the object's initialization function returns, and when that happens, the program quits. How do I somehow wait until this object is deleted before the program quits?

Summary:

  1. main() creates instance of object
  2. Object listens
  3. Connection received
  4. Object's initialization function returns
  5. main() exits (!)

What I want is for main() to somehow delay until that object is finished with what it's doing (aka it will delete itself) before it quits.

Any thoughts?

A: 

It would be easier to answer with confidence if you posted some code, but it seems straightforward enough.... add a while(1) loop around the contents of your main():

int main(int, char **)
{
   while(1)
   {
      [...]
   }
}
Jeremy Friesner
The problem is, that would continue to create multiple objects. The line in main() is this: `NetworkLink *networkLink = new NetworkLink(new UNIXSocketServerCommProtocol());` Unfortunately I can't post any additional code here; it's confidential at the moment. However, I can say that the comm class works fine. It's just that the program quits before it has the chance to work.
jfm429
Also, I might also add that adding a while(1) loop AFTER the object creation is not an option either; one of our requirements is efficiency (the program will be eventually embedded on a remote robotic system) so battery life is critical. If it uses up excessive processor cycles, it won't work.
jfm429
You'll need to put a networkLink->waitForSessionToEnd() call at the end of the loop iteration then. That call should block until the TCP connection has become disconnected. (if the object doesn't have a call like that, then you'll need to add one. As a subsequent answer suggests, pthread_join() will probably be part of the implementation of that method)
Jeremy Friesner
That makes sense; I just don't see how it would block without using up CPU. I know you can have a boolean variable and then do while(!var), but again that's CPU intensive. I've asked a lot of people how to do non-CPU-intensive blocking calls but could never get a good answer that worked - maybe you could suggest something?
jfm429
Also the network class itself does NOT use threads, if that makes a difference.
jfm429
A: 

There are several possible solutions, but without further information it is hard to decide which one is the best in your situation.

My first idea would be to put the communication part in a different thread. This makes programming slightly more complicated, but when the connection closes, only the thread terminates.

A second idea would be a variation on Jeremy Friesner's idea with the while loop. You seem to object to it because of efficiency. My advise: build something that works first, deal with efficiency later. To save resources, put in a sleep() call after the constructor.

Michael Ulm
A: 

What I want is for main() to somehow delay until that object is finished with what it's doing (aka it will delete itself) before it quits.

That sounds to me like the object is starting a thread.

Assuming that is the case, you have a couple of choices:

  1. Call pthread_join to wait for the thread started by the object to finish.
  2. Have main call pthread_exit. This will just end the thread instead of the entire process.
R Samuel Klatchko
A: 

If the object is starting a thread, maybe there is a chance there is some kind of .wait() method in the API or you can reach the inside thread object and make a join()?

If there isn't and you can't change the API, then you'll have to have a while(1) and a sleep inside.. and may not look very nice.

It seems your Network class starts a thread without you knowing or having the ability to wait for it. If the Network class does do everything you need, what the point of using threads inside it because you have only one client at the same time?

Nikko
A: 

Classically a server has a listening socket and you loop accepting client connections, creating a new connection-handling class for each one that executes in a separate thread.

EJP