Multiple TCP clients with Cinder-Asio


#1

Hi all,

I’m starting on a block for some Master/Slave functionality using Cinder-Asio. I have multiple slaves connecting to a master, they all seem to connect yet the onAccept handler in the master is only called the first time. So when I go to send the slaves a message I only have 1 active session to do so.

At the end of this thread on the old forum @banthrewind mentions a strategy for dealing with this but it seems to require onAccept being called so that you can get the socket from the session passed in.

There is a sample app that shows the issue in the repo I am working on here. The one app creates instances of both the master and slaves and simply tries to send them the frame number. You can see it only working for the first slave.

Any help appreciated - dealing with Asio directly seems pretty tricky.
Cheers,
nay.

EDIT - Note that I am actually using this branch thanks to @ryanbartley , the original is not compiling for me at the moment.


#2

Hi Nay,

Unless I’m mis-understanding the question. If you want to accept any amount of clients, all you have to do is call accept again from within your “onAccept” function. I am not next to my computer right now but either the class that you’re listening to the server with, or the server impl itself. The “acceptor” can just listen over and over. Basically,

call accept -> which listens for the first connection.
get called onAccept -> which passes you the connection.
call accept again -> which listens for the next connection.
get called onAccept -> which passes you the next connection.
and on and on for as many as you’d want.

I’ll take a look at the code when I get home but that should be what you’re looking for.

Best,
Ryan


#3

Thanks Ryan,

I tried this previously by calling accept at the end of onAccept but this caused a crash. I’d be curious to know if this works for you.

|error  | void cinder::app::AppBase::executeLaunch()[137] Uncaught exception, type: std::__1::system_error, what: set_option: Invalid argument
libc++abi.dylib: terminating with uncaught exception of type std::__1::system_error: set_option: Invalid argument

After your message I tried calling it again later in the program with an error (Connection reset by peer) but no crash so I added a delay between the connection attempts and it worked. I guess if I slow down the connection logic in the master and have the slaves keep trying until they connect then that should work (as they would when separated out into their own apps anyway). However, in this case the slaves were registering as connected when it seems they weren’t so I’ll have to see how that pans out as I implement this.

Cheers,
nay.


#4

Sorry it took so long to get back to you. I need to reset my notifications for the new forums. I will try this today and get back to you, asap.


#5

I see the problem. I broke out a branch on my repo, called TcpServerListen, which just abstracts the listen portion of the acceptor. Basically, the Acceptor is the “Server”, so you should only create it once (sorry I didn’t look at it closely enough when I replied to you).

In essence, the change allows you to call accept, which will create the acceptor. Then listen is called from within accept, to accept the first connection. Then after it gets a connection, it calls your connection-accepted handler, if there are no errors. After it gives you the session, it calls listen again, which creates the new session, by-passing the acceptor creation, and asynchronously accepts another connection. Rinse-Repeat.

Try that and let me know if it worked. I also updated it so that you can “cancel” the acceptor from within your connection function, in the case that you want to only accept n-connections. Just call cancel. Note: if you cancel the Acceptor/“Server”, you may get an “operation_aborted” error, which is likely directly related to the cancel/close operation of the acceptor. Something to keep in mind.


#6

Thanks so much Ryan, no worries re slow reply - thankful for the help!
That makes sense. The update works even if I go back to having them all try and connect at the same time, which is great.


#7

I went ahead and merged Ryan’s updates into master. It’s also worth looking at the “ssl” branch as it received some updates beyond just adding SSL. I’ve had more pressing needs with VR lately, so this block needs some love.