Winsock Problem: Unable to receive data
I'm experiencing short data receiving comming from our host.
Say, I'm expecting to receive 20 records from our host but the data received was only 10 or sometimes 13 records only.
But I tested our project in our head office, running from VB6 Debug Mode and the expected result was good.
In Released version, I tried to ran the project in a remote branches and the problem still exists. We expected to receive 30 records but what we received only 13 records. We use TCP/IP, Windows XP (end-users) and Windows Server 2003 for our server.
We tried to clone my computer and installed the project to the same remote branch running the released version, no problems encountered.
Please advice.
[749 byte] By [
rpc86] at [2007-11-20 11:03:43]

# 1 Re: Winsock Problem: Unable to receive data
Do you know which records you missed? As in - are the missed records randomly distributed, or is it that you are always missing the last/first ones to be sent?
Edders at 2007-11-9 13:55:42 >

# 2 Re: Winsock Problem: Unable to receive data
Do you know which records you missed? As in - are the missed records randomly distributed, or is it that you are always missing the last/first ones to be sent?
Project Overview
The project is a banking system. There are times that clients request for PASSBOOK UPDATE. For instance, a client would go to the bank and bring his passbook to be updated. Say, the total lines to be updated are 25 lines. The system would only print upto 12th line. The remaining 13 are missing but if we check from our host, the 13 records have been sent correctly.
What I've been wondering is why if we run the project in our Head Office (Development), the system works fine. Or if we run the system in a Dial-Up connection, no problem would be encountered.
If we run the system in a remote area (TCP/IP) , then only 12 records are captured.
Please advice.
rpc86 at 2007-11-9 13:56:42 >

# 3 Re: Winsock Problem: Unable to receive data
Might they have updated to IE7? They messed with the timeout setting.
# 4 Re: Winsock Problem: Unable to receive data
Might they have updated to IE7? They messed with the timeout setting.
my development machine is IE7 as well as the end-users.
rpc86 at 2007-11-9 13:58:37 >

# 5 Re: Winsock Problem: Unable to receive data
I presume what happens is that your TCP packet containing 25 lines are somewhare along the route repackaged into multiple packets. The first packet contains the first 13 lines, the rest goes into a second packet. This repackaging is allowed by the standard - TCP does not preserve boundaries - this means that data sent in one single call to "send" may well require four separate calls to "recv" before you have all the data.
On your local network there may not be a router present that repackages the data - so if you send all in one single packet you will be likely to receive all in one single packet.
If you only do a single recv on the socket then chances are you only get the first packet and miss the second one. You may find that doing another recv (maybe a few ms later) will give you the rest of the packet. The best thing is to somehow include the total datasize in your first packet so that the receiving application can easily find out if all the data has been received or that it needs to do another call to "recv".
Edders at 2007-11-9 13:59:47 >

# 6 Re: Winsock Problem: Unable to receive data
I agree that this is almost certainly the source of the problem. Many programs are written with the mistaken assumption that one call to send() will translate to one corresponding call to recv(). As Edders has correctly pointed out, TCP is free to regroup calls to send() however it wants. Five calls to send() might translate into one call to recv(), or it might translate to ten calls to recv(). In addition, one single call to send() might translate to multiple calls to recv(), i.e., TCP is permitted to break up your data into multiple groups.
This is because TCP is a stream-based protocol. It sends a stream of bytes. It's up to you to interpret those bytes. If you want to preserve messages, or if groupings of the bytes are important (as they usually are), then it's up to the programmer to establish some sort of application-level protocol that allows the program to determine when one complete message has been received, and to determine when multiple messages (including a fragment of a message) has been received.
One common technique is to pre-pend each transmission with the length of the transmission. The recipient can then use the received length to determine how many more bytes are expected. Please note that if you send a multi-byte length length preface (for example, a four-byte integer), then the preface itself might be broken up by TCP, so it's important to check that all four bytes of the preface have been received before trying to interpret what those bytes represent.
Mike
# 7 Re: Winsock Problem: Unable to receive data
In my experience i have used communication protocol that
checking how many bytes was sent and how many bytes was received.
If sent byte != received byte then attempting to resend.
# 8 Re: Winsock Problem: Unable to receive data
I mentioned IE7 because I suspected that the local offices suffered from latency issues, so that 30 seconds is not long enough to receive everything.
# 9 Re: Winsock Problem: Unable to receive data
Thank you for your comment.
To Edders, MikeAThon:
If there is a TCP packet concern here, why does a cloned computer work for the other branches.
I say cloned computer because I cloned my development machine.
The project was written in VB6, and our Host is AS/400.
Please help.
Thank you
rpc86 at 2007-11-9 14:03:41 >

# 10 Re: Winsock Problem: Unable to receive data
If there is a TCP packet concern here, why does a cloned computer work for the other branches.
If the streaming nature of TCP is the cause, then the application might work perfectly well some of the time, and not work at other times. THis is because the way that TCP groups bytes into a packet is non-deterministic, and depends on many factors such as network load, complexity, number of routers between source and destination, etc. Usually, for example, a novice to TCP will find that his incorrect application works perfectly fine when using the loopback address (127.0.0.1), or when tested inside a simple LAN. In this case, TCP tends to group data almost precisely the same way as the calls to send() and recv(). The entire application then fails when deployed over a actual network or over the Internet, since in this deployment, TCP almost always groups the data in ways that are completely different from the corresponding calls to send() and recv().
Mike
# 11 Re: Winsock Problem: Unable to receive data
If the streaming nature of TCP is the cause, then the application might work perfectly well some of the time, and not work at other times. THis is because the way that TCP groups bytes into a packet is non-deterministic, and depends on many factors such as network load, complexity, number of routers between source and destination, etc. Usually, for example, a novice to TCP will find that his incorrect application works perfectly fine when using the loopback address (127.0.0.1), or when tested inside a simple LAN. In this case, TCP tends to group data almost precisely the same way as the calls to send() and recv(). The entire application then fails when deployed over a actual network or over the Internet, since in this deployment, TCP almost always groups the data in ways that are completely different from the corresponding calls to send() and recv().
Mike
What are send() and recv() functions ? Are these VB6 functions? How will I test the bytes sent and receive, what are the commands ?
Thank you.
rpc86 at 2007-11-9 14:05:51 >

# 12 Re: Winsock Problem: Unable to receive data
send() and recv() are winsock functions, which is the first word in your topic ("Winsock Problem: Unable to receive data").
I see now that your first post also mentions VB6. I can't help you with VB6, sorry, but surely there are similar-sounding functions.
Mike
# 13 Re: Winsock Problem: Unable to receive data
I have nothing to add to MikeAThon's replies and unfortunately my knowledge of vb is very limited. Still, the underlying networking stack is of course the same for vb and c; the same kind of problem will have the same kind of solution regardless of the programming language used.
What are the names of the functions you use to send and receive data in vb?
Edders at 2007-11-9 14:07:47 >

# 14 Re: Winsock Problem: Unable to receive data
What is the size of the buffer for incoming data which you used in recv() function? May be that is little less than the size of all the records( or data ) which you receive from host. Try incresing it to maximum value and let me know the results.
# 15 Re: Winsock Problem: Unable to receive data
What is the size of the buffer for incoming data which you used in recv() function? May be that is little less than the size of all the records( or data ) which you receive from host. Try incresing it to maximum value and let me know the results.
1024 Bytes only
rpc86 at 2007-11-9 14:09:57 >

# 16 Re: Winsock Problem: Unable to receive data
Could you maybe post a short piece of code that shows how you have implemented the receiving side of your application?
Edders at 2007-11-9 14:10:50 >

# 17 Re: Winsock Problem: Unable to receive data
Could you maybe post a short piece of code that shows how you have implemented the receiving side of your application?
Here is the code below.
NOTE !!
The AxGlobal.gMSMesg "Transaction Timed Out. Perform Last Transaction Inquiry." will be activated if the variable sDATA receives no data, please also check the condition...
If Trim(sData) <> "" Then
Call MSGetReturnCode(sData, sResend)
Else
g_bTimeOut = True
GoTo ReTry
End If
Here is my complete code entitled gMSSendHost()
Public Sub gMSSendHost(Optional sReturnMsg As String, _
Optional bIsStoreNForward As Boolean = False, _
Optional sJrnlSeqNo As String = "", _
Optional sTrancode As String = "", _
Optional sDetailData As String = "")
Dim sSendData As String * 4096
Dim lRC As Long
Dim sData As String
Dim sResend As String
Dim delay_Cnt As Integer
Dim delay_sDATA As Integer
Dim Retry_Count As Integer
Dim Try As Integer
Dim Msg_Switch As Integer
On Error GoTo err_handler
Screen.MousePointer = vbHourglass
g_sTrxStatus = "Accepted"
bDisplayMsg = False
g_bTimeOut = False
m_bIsStoreNForward = bIsStoreNForward
MSInitHostVar
bPassbook = False ' Passbook Printing
Set m_objPrnPrint = New AxOliPrt.CPBPrinter
m_objPrnPrint.DeviceName = AxGlobal.gMFGetLocalHostName
m_objPrnPrint.InitPrinter
g_szSendBuffer = ""
Do
DoEvents
'Normal Transaction
If bIsStoreNForward = False Then
sSendData = MFConstructData(sJrnlSeqNo, sTrancode)
g_szSendBuffer = sSendData
'store and forward
Else
sSendData = sDetailData
End If
'sResend update in host response header
sResend = ""
'Online
AxGlobal.gMSRetRef_gbBranchMode g_bBranchOnlineMode
If Not g_bBranchOnlineMode Then
GoTo Err_HostCommFail
End If
If objSli.Online Then
objSli.Write Trim(sSendData), Len(Trim(sSendData))
'Write Fail
If objSli.LastErrorCode <> 0 Then
GoTo Err_HostCommFail
End If
'Offline
Else
GoTo Err_HostCommFail
End If
Do
DoEvents
Screen.MousePointer = vbDefault
sData = Space(1024)
lRC = objSli.Read(sData)
'Read Fail
If objSli.LastErrorCode <> 0 Then
GoTo err_handler
Else
If Trim(sData) <> "" Then
Call MSGetReturnCode(sData, sResend)
Else
g_bTimeOut = True
GoTo ReTry
End If
End If
Loop Until objSli.EOM = 1
Loop While sResend <> ""
If (bPassbook = True) Then
m_objPrnPrint.AxPrint "99|" ' Eject
End If
Set m_objPrnPrint = Nothing
Screen.MousePointer = vbDefault
Exit Sub
Err_HostCommFail:
If (bPassbook = True) Then
m_objPrnPrint.AxPrint "99|" ' Eject
End If
Set m_objPrnPrint = Nothing
sReturnMsg = sSendData
If g_bBranchOnlineMode Then
AxGlobal.gMSMesg "Host is offline"
End If
g_sTrxStatus = "Offline"
Screen.MousePointer = vbDefault
MSGetSOForOffTrx
Exit Sub
err_handler:
If (bPassbook = True) Then
m_objPrnPrint.AxPrint "99|" ' Eject
End If
Set m_objPrnPrint = Nothing
If g_bTimeOut = True Then
AxGlobal.gMSMesg "Transaction Timed Out. Perform Last Transaction Inquiry."
gMSClose
End If
If Err <> 0 Then
AxGlobal.gMSMesgErr "gMFSendHost"
End If
g_sTrxStatus = "Pending"
Screen.MousePointer = vbDefault
End Sub
rpc86 at 2007-11-9 14:11:59 >

