Archived Forum Post

Index of archived forum posts


Socket Reading Blocks Writing?

Dec 28 '16 at 09:20

We already exchange from specific support for implementing your Socket library for a Listener under VB6.

Now, I have switched to VB.NET and play with asynchronous tasks and Handles. It works well but I do observed a strange behaviour with following scenario.

  1. Launch a Receive task to listen client: Dim receiveTask As Chilkat.Task = mySocket.ReceiveStringUntilByteAsync(Asc(vbCr))

  2. In mySocket_OnTaskCompleted, I do analyse message and re-run a new receivedTask to maintain litening

  3. When some events fired, I need to send message to client (not in response to client message but external trigger), then I launch a Send task to client: Dim sendTask As Chilkat.Task = mySocket.SendStringAsync(txtResponse & vbCr) I do use Task.userData to discriminate OnTaskCompleted handles actions between receiveTask and sendTask.

My problem is that I observed a throuput limitation in sendTask (external trigger may fire many time in 1s). When I defined the sendTask, it seems that it just wait for "mySocket.MaxReadIdleMs" before defining sendTask (probably like with the receiveTask running) and then I lost the asynchronous advantage. I exchange short message with client so I do place MaxReadIdleMs to 2000 but it create a candenced sendTask every 2s where I want it more reactive.

I do try to "Cancel" receiveTask before defining sendTask but I do observed same behaviour. Did I miss to something or is it normal ?

Accepted Answer

The problem is solved by using CloneSocket.

Each Chilkat object is thread-safe, and this is implemented by the fact that only a single call can be active for an object instance at a time. For example, if there is an object Chilkat.Something, and an application has two threads, and each thread simultaneously calls a method on Chilkat.Something, then the calls will execute one after the other (not simultaneously).

For a Chilkat.Socket object however, it is desirable to be reading while simultaneously writing. The solution is to call CloneSocket to get a new Chilkat.Socket object that shares the same underlying connection. Internally, the thread-safety for the underlying socket connection is finer-grained. It allows for reading while writing at the same time. (If two threads try to both write at the same time, then one write will follow the other. The same is true for two threads trying to read at the same time (one must follow the other). However, a read can proceed at the same time as a write.

You would use one socket object for reading, and the other for writing. For example:

// Use mySocket for reading, and mySocket2 for writing.  Both share the same underlying connection.
Chilkat.Socket mySocket2 = mySocket.CloneSocket();