• Welcome to Valhalla Legends Archive.
 

Requested Help (Hardcore VB Helpers)

Started by n00blar, March 23, 2003, 11:36 PM

Previous topic - Next topic

n00blar

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!

n00blar

#1
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.

Skywing

#2
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.

n00blar

#3
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.

Banana fanna fo fanna

I think you're teetering the realm of where development in VB becomes slower than other languages.

n00blar

#5
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.

Banana fanna fo fanna

I'm just trying to keep my karma rating down.

n00blar

#7
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!

Banana fanna fo fanna


dim procRunning as boolean

sub myproc()
if procRunning then exit sub
procRunning = true
'do whatever
end sub

n00blar

#9
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!

Zakath

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.
Quote from: iago on February 02, 2005, 03:07 PM
Yes, you can't have everybody...contributing to the main source repository.  That would be stupid and create chaos.

Opensource projects...would be dumb.

n00blar

Problem has already been solved with some of Yoni's assistance (thanks again man),  however, I want to thank you guys for replying.

Zakath

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?
Quote from: iago on February 02, 2005, 03:07 PM
Yes, you can't have everybody...contributing to the main source repository.  That would be stupid and create chaos.

Opensource projects...would be dumb.

Grok

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.

Banana fanna fo fanna

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.