Valhalla Legends Archive

Programming => General Programming => Topic started by: n00blar on March 23, 2003, 11:36 PM

Title: Requested Help (Hardcore VB Helpers)
Post by: n00blar on March 23, 2003, 11:36 PM
I will state the conclusion I came to, but first let me give you some info on the problem & code.   This is a server, developed using the visual basic 6.0 ide, using the winsock api (thx to subclassing).   The server uses asynchronous non-blocking sockets.  I'm having a problem with using the visual basic debugger, however, everything seems to run perfectly when debugging isn't present.   The problem causes packet chunks (when data isn't all received and multiple calls to recv are required) to be received backwards.   So the end of the packet is received first and the first is received last.   If you need a better explanation after reading on tell me.

(Code selection from CServer.ISuperClass_After(...) (this is like a message handler called after default wnd proc))
Where wParam == Socket Handle

           ...
           Case FD_READ        'Issues notification of readiness for reading.
               RaiseEvent OnDataArrive(wParam)
               lReturn = 0
           ...


(Code select from FrmMain.OnDataArrive(...))

Private Sub Server_OnDataArrive(ByVal SocketHandle As Long)
   Const MAX_BYTES = 127
   Dim TotalBytes As Integer
   Dim Buffer(MAX_BYTES) As Byte
   Dim tmpBuffer As String
   
   TotalBytes = recv(SocketHandle, Buffer(0), MAX_BYTES, 0)
   tmpBuffer = StrConv(Buffer, vbUnicode)
End Sub


The problem occurs when I am debugging and the packet isn't received all at once, so it has to make multiple calls to receive.  The conclusion I came to was that when in debug mode, when the last recv (the one receiving the last part of the packet) is called it immediately goes to the next line and works its way out of each call to OnDataArrive().  Thus recv'ing the packet "backwards".  This all being evil vb6 debugger's fault!
Title: Re:Requested Help (Hardcore VB Helpers)
Post by: n00blar on March 24, 2003, 02:32 PM
Hmm.. does anyone want to reply and tell me what they think about my conclusion? Oh and here is an example of what it would look like...

Client Sends> Hey there you look like a male stripper on cocaine.
Server Recvs (Half) > like a male stripper on cocaine.
Server Recvs (Other Half) Hey there you look

It recv's the chunks in reverse order, only when i'm debugging though.  Otherwise, everything is cool.
Title: Re:Requested Help (Hardcore VB Helpers)
Post by: Skywing on March 24, 2003, 02:36 PM
Quote from: n00blar on March 24, 2003, 02:32 PM
Hmm.. does anyone want to reply and tell me what they think about my conclusion?
I think that always receiving into the start of the buffer when you might have data remaining in there if there was a partial message received is rather suspect.

Also, do you handle recv failing (returning a zero or negative value) because of a disconnect or otherwise?

Note that recv failing does not necessarily mean the connection has been lost.  For example, it's not uncommon to have recv fail with WSAEWOULDBLOCK after getting a data-arrival notification, in which case you should simply try calling recv again later.

P.S. Overlapped I/O would be much more efficient than WSAAsyncSelect for a server.
Title: Re:Requested Help (Hardcore VB Helpers)
Post by: n00blar on March 24, 2003, 02:40 PM
Quote
I think that always receiving into the start of the buffer when you might have data remaining in there if there was a partial message received is rather suspect.

I have tried it another way by receiving like this

....
NewBytes = recv(SocketHandle, Buffer(TotalBytes), MAX_BYTES - TotalBytes, 0)
....


Quote
Also, do you handle recv failing (returning a zero or negative value) because of a disconnect or otherwise?

In the example i've posted, no, however in my code I do handle returning zero and negative values.
Title: Re:Requested Help (Hardcore VB Helpers)
Post by: Banana fanna fo fanna on March 24, 2003, 04:14 PM
I think you're teetering the realm of where development in VB becomes slower than other languages.
Title: Re:Requested Help (Hardcore VB Helpers)
Post by: n00blar on March 24, 2003, 04:25 PM
Quote
I think you're teetering the realm of where development in VB becomes slower than other languages.

I agree, however, only specific parts may take longer to develop. Furthermore, once in place they are all reusable (perhaps another project?) and then you can quickly develop the rest of the application.  I don't want this thread to become a "language war" please stay on topic and reply only /w help if possible.
Title: Re:Requested Help (Hardcore VB Helpers)
Post by: Banana fanna fo fanna on March 24, 2003, 06:11 PM
I'm just trying to keep my karma rating down.
Title: Re:Requested Help (Hardcore VB Helpers)
Post by: n00blar on March 28, 2003, 01:24 PM
While no one wanted to/could post any help, I think I might have figured out the problem, however solving it is the issue I'm at now!

I thought about how the VB Winsock Control worked and this is what I came to...

VB is single thread so new incoming data will be queued for you. The DataArrival event will not be called while you are already processing one.  The exception to this is if you call DoEvents in the DataArrival event. This allows the process time to go off and handle pending events. This can allow the DataArrival to fire again.

So now the solution is making sure that my event isn't fired if its already inside of one? I don't know if this will help or not, but I thought it was worth a try! :D  If anyone could post a method of using the "solution" I would appreciate it!
Title: Re:Requested Help (Hardcore VB Helpers)
Post by: Banana fanna fo fanna on March 28, 2003, 01:59 PM

dim procRunning as boolean

sub myproc()
if procRunning then exit sub
procRunning = true
'do whatever
end sub
Title: Re:Requested Help (Hardcore VB Helpers)
Post by: n00blar on March 28, 2003, 02:11 PM
I have a feeling this wont work, because if it issued the FD_READ call and I don't handle it then that data won't be recieved, so the next time I do handle a FD_READ it will... well I don't know if this is the best way storm, contact me on aim/icq/msn if you feel it is... and tell my why you feel it is, and thanks for the reply though!
Title: Re:Requested Help (Hardcore VB Helpers)
Post by: Zakath on March 28, 2003, 03:39 PM
If you issue a recv to a socket in response to an FD_READ event, and you don't retrieve all the information pending on the socket, it'll send another FD_READ event. So I think St0rm's method would work...not sure how efficient it is though.
Title: Re:Requested Help (Hardcore VB Helpers)
Post by: n00blar on March 28, 2003, 07:33 PM
Problem has already been solved with some of Yoni's assistance (thanks again man),  however, I want to thank you guys for replying.
Title: Re:Requested Help (Hardcore VB Helpers)
Post by: Zakath on March 29, 2003, 01:33 AM
Hey, however much I make sarcastic remarks and snipe at the idiots (and respond to their requests for free code with C++ snippets they don't understand), I'm still here to help out the real programmers. No thanks required, isn't that what this forum is for?
Title: Re:Requested Help (Hardcore VB Helpers)
Post by: Grok on March 29, 2003, 01:47 PM
i require massive amounts of thanks.  you can express it in terms of songs written to worship me, lots of +++ to my karma, and cash donations to my paypal account ([email protected]).







ok, forget the songs or karma points.
Title: Re:Requested Help (Hardcore VB Helpers)
Post by: Banana fanna fo fanna on March 29, 2003, 04:50 PM
Quote from: Zakath on March 29, 2003, 01:33 AM
Hey, however much I make sarcastic remarks and snipe at the idiots (and respond to their requests for free code with C++ snippets they don't understand), I'm still here to help out the real programmers. No thanks required, isn't that what this forum is for?

Same here.