Is there a downside to using synchronous socket calls in a dedicated thread?

I am writing a server client socket application and have got to choose between synchronous and asynchronous patterns.

 

In a single threaded process I can see why it is advantages to use the asynchronous calls - you can do something else whilst waiting for incoming coms.  But the async calls are a bit mind bending so...

 

I could use blocking socket synchronous/calls in a separate dedictated thread.  That way the main thread is not blocked.  This is a much simpler solution to code than the asynchronous calls but it seems too good to be true.

 

Can anyone see a significiant downside to this approuch    For instance do the blocking socket calls use loads of resrouces

 

Thanks in advance for any comment.




Answer this question

Is there a downside to using synchronous socket calls in a dedicated thread?

  • Colin Hardie

    RizwanSharp, I have read your reply here,

    http://forums.microsoft.com/MSDN/ShowPost.aspx PostID=1220140&SiteID=1

    I'm wondering if you have any source code to share Anyone

    Thank you,

    awni


  • Justin England

    OK this is great.

    These posts have been VERY useful both in helping my understanding of how sockets work and helping me make decisions.

    I have opted to use the synchronous 'Listen' call on the server and then use the asynchronous model for each connection one it has been 'floated' off after each 'Accept'.

    I notice that the examples of asynchronous sockets use shared/static functions as call backs and then past the 'type-less context object' thru the asynchronous calls. This makes the examples hard to follow and involves down casting the context object each call back which I was always told was a no-no. It also seems to necessitate the use of wait objects to mediate between something I can't quite make out.

    I implemented the system passing in the address of NON shared functions on my 'Connection' object so that the context was right there for the call backs and no need to downcast anything. I guess the 'AddressOf' command is actually returning some kind of delegate object which encompasses the object instance as well as the function address to accomplish this magic.

    Here is an abbreviated pseudo VB code example of how I did it. It seems a much nicer way to do things than the way in the examples. It seems to work fine, Is there any downside to doing this way and not using shared/static functions as call-backs.

    The ides is that you create an instance of the CConnection class handing it the socket you got back from Listen. Then you call Start after which the connection deals with the byte stream as it arrives in ' ReceiveCallBack' I have omitted loads of housekeeping and not dealt with Sending but you get the idea. Is there anything fundamentally wrong with this approach It worries me a bit that I can find no reason to use any wait handles as the example using shared/static functions did.

    class CConnection

    private m_buffer(1024) as byte

    private m_ socketHandler as socket

    private m_iReceiveCount as int32 = 0

    sub New (byval socketHandler as socket)

    m_ socketHandler = socketHandler

    end sub

    sub Start()

    m_ socketHandler .BeginReceive(m_buffer , 0,1024,0, addressof ReceiveCallBack , nothing)

    end sub

    sub ReceiveCallBack(ByVal ar As IAsyncResult)

    dim iNumReceived as int32 = m_ socketHandler .EndReceive(ar)

    if iNumReceived > 0 then

    'access my context data

    m_iReceiveCount+=1

    'do stuff with the data recieved

    'back to waiting

    m_socketHandler .BeginReceive(addressof ReceiveCallBack)

    endif

    'connection ended

    m_iReceiveCount +=1

    end sub

    end class



  • Danielha

    This is not a answer to your question, it is rather a related question. How many concurrent connections can be maintained by an average Pentium 4 computer I need about 10,000 clients connected to my server at the same time. They only send small packets(less than 100 bytes) at a time. They don't all send their data at the same time, but you can expect at least 2000 of them to send together at any one time. Can a pentium 4 handle this or do I need to use network load balancing and so on

    regards,

    awni


  • vavtnen

    This is yet another embarrassing 'Doh' moment on this forum for me - as I am forced to reply to my own question.

    Having implemented the synchronous pattern I now realize that the huge downside is that you can not receive and send at the same time on a single socket - at least on the same single thread.

    In order to receive you must be blocked inside a 'Receive' function. This naturally precludes calling the 'Send' function - at least on that thread.

    I wonder if you could call the send function on that socket in yet another thread Sockets are - after all - thread safe. Would the send call just block until the Receive call had returned or would it happily send on the calling thread whilst the receiving thread was blocked

    Actually I suspect it would do the latter and work just fine but now I would be managing two additional threads for each connection and it might be easier just to use the asynchronous pattern in the first place - which I suspect uses thread pooling anyway! At least that way I don't have to manage the threads myself.

    If anyone has any comments I am still very interested in hearing them.



  • dr.acv

    When Socket is reading Synchronously in a seperate thread you can still send data to it to relay to the network from another thread. The other thread may be your UI or main Thread which will not create any difference as it blocks in reading case because all it has to do is to write some data on the network and give control back to its caller immediately while in reading scenerio a Read or Receive function block execution untill it receives something.

    But using Synchronous socket is OK when you have to deal with 5-10 cleints or more but not for 1000 or more clients because you know that it'll require creating 1000 threads and you can expect what your application will do with CPU.

    I would recommend using combining both Asynchronous and Synchronous Sockets without using any thread, which will lead to a simpler, managable and roboust solution for your network application.

    For more details please read my answers in this thread:

    http://forums.microsoft.com/MSDN/ShowPost.aspx PostID=1220140&SiteID=1

    If you need more help, please feel free to ask about anything.

    Best Regards & Best of Luck,

    Rizwan aka RizwanSharp



  • Ray C

    It is perfectly ok to recv from a socket on one thread and send to it on another, the two don't need any form of synchronisation etc. I've just recently been working on a little diagnostics app, when the connection is made I start a receive thread in the background displaying in a text form, with sending done in the foreground when ever the user enters text and hits <Send>. So its quite common I guess to have the send side driven by user actions. Another application talks using a 'ping-pong' protocol, for each request one response packet arrives, so it just uses one thread: send request, followed by read-until-whole-response-packet. It will depend on the application and the protocol it is using...

    Under the covers the socket operations are fully asynchronous using the base OS's (Windows'/Winsock's) asynchronous features; actually using Overlapped Completion Ports as I understand it. So when using an asynchronous operation in .NET when the operation is blocking waiting for completion there is no thread blocked waiting, the only time that the thread pool is used is if the operation has a callback method set and then a thread pool thread is used to execute it.

    Finally the asynchronous operations are particularly useful when writing an application that has many connections open at the same time; when a server has 10000 connections then it better not be using a thread (or two) for each one! :-) Because of the above very efficient socket usage sockets in .NET can handle this.



  • Is there a downside to using synchronous socket calls in a dedicated thread?