Bidirectional nature of sockets

Hi Experts,

Please correct me if I'm wrong on any of this and maybe throw in some goodies?

I would like to set up a client and server that communicate over a socket.  It is my understanding that I can write or read to this socket at any time, thus, the client and server may both contain a read and write thread (so 4 threads if client and server happen to be on the same machine).  Is is ok if the read thread polls and reads every so often while the write thread writes?  i.e., on one socket, are there two separate channels that don't affect eachother at all?

Thank you!
Mike
LVL 1
threadyAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Mike TomlinsonHigh School Computer Science, Computer Applications, and Mathematics TeachersCommented:
That's all correct.  The read and write channels operate independently.

Typically you have two options when dealing with the read side:
(1) Continuously Poll and check some kind of "data available" flag/counter on the read stream to determine when to actually read buffered data.
(2) Place a blocking read call into another thread.  It will just sit there and won't return until data is received.  The blocking call is placed into a loop so that as long as there is data left in the buffer it will continue reading.  Since it is blocking, though, once all data has been read it will block again.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
threadyAuthor Commented:
Excellent!  With option 2, it complicates termination/shutdown a lot though right?  How would you terminate that elegantly?
0
threadyAuthor Commented:
Just a timeout I guess- within the read (within the loop)?
0
Become a Certified Penetration Testing Engineer

This CPTE Certified Penetration Testing Engineer course covers everything you need to know about becoming a Certified Penetration Testing Engineer. Career Path: Professional roles include Ethical Hackers, Security Consultants, System Administrators, and Chief Security Officers.

Mike TomlinsonHigh School Computer Science, Computer Applications, and Mathematics TeachersCommented:
It depends on the framework you're using.  In C#, you can set the IsBackground() property of the Thread to True which causes it to automatically be terminated when the application is shut down.
0
BuggyCoderCommented:
adding to it, if you use tcplistener and call its start method, it will start a thread pool thread in background and start listening for the request.
Thread pool threads are much safer than opening your own threads are Threadpool is more effecient in handling threads....

here is an example:-
http://www.codeproject.com/Articles/2418/Making-Socket-Based-Application-Using-TcpListener
0
Mike TomlinsonHigh School Computer Science, Computer Applications, and Mathematics TeachersCommented:
You could also a Timeout feature if one is available.  This makes it essentially the same as polling in a loop (just be sure to check if there is data available before reading though).
0
jkrCommented:
>>Is is ok if the read thread polls and reads every so often while the write thread writes?

You can do that, but instead of polling, I'd use 'select()' to wait until data is available, i.e.

fd_set readfd;
timeval tv;

FD_ZERO(&readfd);
FD_SET(mysock,&readfd);

tv.tv_sec = TIME_IN_SEC;
tv.tv_usec = 0;

select(0,&readfd,NULL,NULL,&tv);

// data is now available

Open in new window

0
ambienceCommented:
I would suggest against a thread (actually two threads per socket) design. This would inevitably lead to the antipattern "super-threading." Unless the number of sockets per program is going to be pretty small its easier to use a threaded server or client because of the simplicity, but if there are say 100 sockets you have 200 threads. Of course most of the time they'd be sleeping but still this isnt scalable beyond a certain degree.

I would recommend two additional patterns to look into,

- The Reactor pattern elegantly implemented by POCO here http://pocoproject.org/docs/Poco.Net.SocketReactor.html

The idea here is that theres a reactor object that watches (using select() internally or any other mechanism) multiple sockets, and your supplied delegate is called back for IO events. The reactor is supposed to be intelligent enough to adapt to growing needs. I have a SocketReactor that uses a grow-able thread group internally and a single thread handles 64 sockets. SocketReactor is good because it is easy to make it portable if you only use the posix API for sockets.

- Use the boost asio package http://www.boost.org/doc/libs/1_49_0/doc/html/boost_asio/tutorial/tutdaytime7.html

Very easy to use abstraction over Asynchronous socket IO and uses IO Completion ports on Windows which makes it really scalable. Once you get past the basic hurdles of thinking in terms of asynchronous design, its pretty easy to use.
0
threadyAuthor Commented:
ambience, I agree with you, but I'm looking at a maximum of about 6-8 threads.  I have data-intensive reads and writes and I want them setup on a live socket that exists for the lifetime of each pair.  Once communication starts, there's a lot of data that goes back and forth and it's a bit in the need for speed.  If the connection is established, I only want to do that once.  I still need time to mull over the answers...  Thanks everyone!
0
ambienceCommented:
>>  I have data-intensive reads and writes and I want them setup on a live socket that exists for the lifetime of each pair.  Once communication starts, there's a lot of data that goes back and forth and it's a bit in the need for speed.

Single thread per socket isnt necesarily going to be faster; there are so many factors that each would affect. I dont think any of the Reactor or IO completion based design would result in slowdown either. Depending upon how intelligent the internal design is the Reactor may sort of starve some sockets if say socket at index 0 is always active (has IO). But like I said, it depends upon the internals.

Threaded servers on the other hands are somewhat easier to code (though easy is a relative term).
0
threadyAuthor Commented:
I'm trying to find out which library to use that would simplify the client to use sockets with.  My goal is to have a bread-and-butter standard c++ socket on the client side.  Does anyone know if I use the standard library for sockets, so that I can easily drop this code into an iPad project as well as on a windows machine inside a native MFC application?
0
ambienceCommented:
Nope - unless you are willing to wait till the next C++ standard comes out and is fully supported across the compiler landscape.

Sockets haven't made into STL yet ... but there are a lot of cross platform toolkits out there that should compile fine for iPad. Boost and POCO - both are cross platform.
0
threadyAuthor Commented:
POCO- right.  You said the magic word!  I really like POCO - I'll have to give it a try that way.
0
threadyAuthor Commented:
Thanks everyone for the terrific help!
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C++

From novice to tech pro — start learning today.