Author | Message | Time |
---|---|---|
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 [code] ... Case FD_READ 'Issues notification of readiness for reading. RaiseEvent OnDataArrive(wParam) lReturn = 0 ... [/code] (Code select from FrmMain.OnDataArrive(...)) [code] 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 [/code] 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! | March 24, 2003, 5:36 AM |
n00blar | 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. | March 24, 2003, 8:32 PM |
Skywing | [quote author=n00blar link=board=5;threadid=803;start=0#msg6336 date=1048537964] Hmm.. does anyone want to reply and tell me what they think about my conclusion? [/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. 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. | March 24, 2003, 8:36 PM |
n00blar | [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. [/quote] I have tried it another way by receiving like this [code] .... NewBytes = recv(SocketHandle, Buffer(TotalBytes), MAX_BYTES - TotalBytes, 0) .... [/code] [quote] Also, do you handle recv failing (returning a zero or negative value) because of a disconnect or otherwise? [/quote] In the example i've posted, no, however in my code I do handle returning zero and negative values. | March 24, 2003, 8:40 PM |
St0rm.iD | I think you're teetering the realm of where development in VB becomes slower than other languages. | March 24, 2003, 10:14 PM |
n00blar | [quote] I think you're teetering the realm of where development in VB becomes slower than other languages. [/quote] 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. | March 24, 2003, 10:25 PM |
St0rm.iD | I'm just trying to keep my karma rating down. | March 25, 2003, 12:11 AM |
n00blar | 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! | March 28, 2003, 7:24 PM |
St0rm.iD | [code] dim procRunning as boolean sub myproc() if procRunning then exit sub procRunning = true 'do whatever end sub [/code] | March 28, 2003, 7:59 PM |
n00blar | 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! | March 28, 2003, 8:11 PM |
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. | March 28, 2003, 9:39 PM |
n00blar | Problem has already been solved with some of Yoni's assistance (thanks again man), however, I want to thank you guys for replying. | March 29, 2003, 1:33 AM |
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? | March 29, 2003, 7:33 AM |
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 (grok@valhallalegends.com). ok, forget the songs or karma points. | March 29, 2003, 7:47 PM |
St0rm.iD | [quote author=Zakath link=board=5;threadid=803;start=0#msg6611 date=1048923192] 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] Same here. | March 29, 2003, 10:50 PM |