Home All Groups Group Topic Archive Search About

Is using raw, uncooked Winsock so bad?

Author
23 Apr 2009 10:44 AM
MM
My "mini newsreader" is coming along nicely, but nevertheless I was
Googling for NNTP ideas, then suddenly decided to whack some minimal
code into a new VB6 app:

Option Explicit

Private Sub cmdConnect_Click()
    sock.RemoteHost = "news.zen.co.uk"
    sock.RemotePort = 119
    sock.Connect
End Sub

Private Sub cmdGroup_Click()
   sock.SendData "GROUP uk.legal" & vbCrLf
End Sub

Private Sub Form_Unload(Cancel As Integer)
   If sock.State = sckOpen Then sock.Close
End Sub

Private Sub sock_DataArrival(ByVal bytesTotal As Long)
   Dim strData As String
   sock.GetData strData, vbString
   txtData.Text = txtData.Text & strData
End Sub

That's all the code! And aleady there's the rudiments of a newsreader.

So all these socket OCXs, are they /really/ necessary? Is
communicating via Winsock directly /really/ so hard?

MM

Author
14 May 2009 8:36 AM
MM
Day Two of my conversion from DsSocket to WinSock (MSWINSCK.OCX ) and
it isn't proving such a minefield as I had expected. (I discontinued
work with DsSocket having been given an outrageous upgrade price from
my VBX version.)

One major difference is that the Winsock control receives data in
chunks that you have to concatenate, whereas DsSocket receives data a
line at a time. Thus it is easier to parse the received data with
DsSocket. However, it isn't that much harder using the Winsock control
and InStr and Split. Another slightly peculiar 'feature' of Winsock is
that if you try to connect (Winsock.Connect) and the connection fails,
you have to do Winsock.Close before another WinsockConnect else you'll
get a 40020 error (Invalid Operation At Current State). This doesn't
happen with DsSocket. You can just repeat the connection attempt
without needing to explicitly close anything. However, once I'd sussed
this with Winsock, it's not a big problem. What I do wish is that the
Winsock control was documented in much more detail.

MM
Author
14 May 2009 10:08 AM
Nobody
"MM" <kylix***@yahoo.co.uk> wrote in message
news:7cln051vvlmske4jco17vig724b4m5pmgv@4ax.com...
> One major difference is that the Winsock control receives data in
> chunks that you have to concatenate, whereas DsSocket receives data a
> line at a time. Thus it is easier to parse the received data with
> DsSocket.

According to DsSocket help file, it behaves the same way as MS Winsock in
regard to DataArrival. The received information can be broken down into
fragments. In most cases, when there is a delay between one "Send" and the
next, it's received in one DataArrival event, unless the amount sent was too
large, but this is never guaranteed.

> However, it isn't that much harder using the Winsock control
> and InStr and Split.

If there is always terminating characters, such as vbCrLf, then it's easy.
However, I recommend that you test your processing code in a new project and
give it test data to cover all cases, so when you use it in the real
project, you wouldn't need to debug two problems at once.
Author
14 May 2009 10:27 AM
Nobody
"Nobody" <nob***@nobody.com> wrote in message
news:u4DXyvH1JHA.4288@TK2MSFTNGP04.phx.gbl...
> In most cases, when there is a delay between one "Send" and the next, it's
> received in one DataArrival event, unless the amount sent was too large,
> but this is never guaranteed.

I want to clarify that I meant to say that each send would have a
corresponding DataArrival event if there is a long enough gap between the
two sends, and the message sent is 536 bytes or smaller(576 - 40 for TCP/IP
header).
Author
14 May 2009 1:08 PM
MM
On Thu, 14 May 2009 06:27:12 -0400, "Nobody" <nob***@nobody.com>
wrote:

>"Nobody" <nob***@nobody.com> wrote in message
>news:u4DXyvH1JHA.4288@TK2MSFTNGP04.phx.gbl...
>> In most cases, when there is a delay between one "Send" and the next, it's
>> received in one DataArrival event, unless the amount sent was too large,
>> but this is never guaranteed.
>
>I want to clarify that I meant to say that each send would have a
>corresponding DataArrival event if there is a long enough gap between the
>two sends, and the message sent is 536 bytes or smaller(576 - 40 for TCP/IP
>header).

With larger articles data is mostly going to be received in more than
one DataArrival event, making it essential to have some kind of
buffering mechanism as the data comes in. Although my rudimentary code
at the moment simply concatenates a static string buffer for each
DataArrival/GetData, my experience has been that concatenating longer
and longer strings (as the buffered data increases in size) becomes
slower and slower.

So I am working on an alternative approach. Probably this will involve
a string array, starting with, say, ten elements (0 through 9). At
each DataArrival an array pointer is incremented and GetBuffer will
stick its data into the next available element. If the pointer, when
incremented, exceeded UBound, then ReDim Preserve will add another
batch of, say, ten elements.

When the terminator is seen, a routine is called to take the contents
of the array for further processing.

As for the terminator, I am working on the assumption that all data
sent by the Usenet server will be terminated with a single dot on a
line by itself (as per RFC). DsSocket always does this, so that it is
easy to determine when the chunk of data in question has been received
in its entirety. With Winsock it's a little harder because the data
chunks are broken up at random and the terminating dot can appear at
the end of the final chunk of data.

For instance, using DsSocket in its Receive event I can reliably check
for:

If ReceiveData = "." & vbCrLf Then...... 'Terminator

but with Winsock I have to do
If right$(ReceiveData, 5) = vbCrLf & "." & vbCrLf Then... 'Terminator

MM