Getting truncated socket bytes

Hi,

I am listening to a port for data but I am not able to recieve whole data, I only get truncated data. Client sends me data that exceeds 40K and the data I recieve in my callback function is always 8K to 9K. I dont get the rest of the data. I think the data size is too big to come in one go and hence it comes in 2-3 sub-packages but my call back function only gets called once hence I am getting truncated data. I am sending the code...Is there anyway I can recieve complete data sent by client

Public Function ConnecttSocket(byVal iPort as integer)

Dim _sHostName As String

Dim _iLocalPort As Integer = iPort

Dim LocalIp() As IPAddress

Dim _oIPHostEntry As IPHostEntry

Dim IPLocalEndPoint As IPEndPoint

oListenerSocket = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)

_sHostName = Dns.GetHostName()

_oIPHostEntry = Dns.GetHostByName(_sHostName)

LocalIp = _oIPHostEntry.AddressList()

IPLocalEndPoint = New IPEndPoint(LocalIp(0), _iLocalPort)

oListenerSocket.Bind(IPLocalEndPoint)

oListenerSocket.Listen(4)

oListenerSocket.BeginAccept(New AsyncCallback(AddressOf onClientConnect), Nothing)

End Function

Private Sub onClientConnect(ByVal asyn As IAsyncResult)

Try

workerSocket = oListenerSocket.EndAccept(asyn)

SocketWaitForData(workerSocket)

oListenerSocket.BeginAccept(New AsyncCallback(AddressOf onClientConnect), Nothing)

Catch ex As Exception

MessageBox.Show("onClientConnect " + ex.Message.ToString())

End Try

End Sub

Private Sub SocketWaitForData(ByVal soc As Socket)

Try

If SocketpfnCallBack Is Nothing Then

SocketpfnCallBack = New AsyncCallback(AddressOf SocketOnDataRcvd)

End If

result = soc.BeginReceive(SocketDataBuffer, 0, SocketDataBuffer.Length, SocketFlags.None, SocketpfnCallBack, Nothing)

Catch ex As Exception

MessageBox.Show("SocketWaitForData " + ex.Message.ToString())

End Try

End Sub

Private Sub SocketOnDataRcvd(ByVal asyn As IAsyncResult)

Dim iRx As Integer = 0

Dim sSocketMessage As System.String

Try

 

iRx = workerSocket.EndReceive(asyn)

'iRx always shows 9K or 8K, I think this is the maximum capacity of sockets to 'transfer data in one go

Dim
chars(iRx + 1) As Char

Dim d As System.Text.Decoder = System.Text.Encoding.UTF8.GetDecoder()

Dim charlen As Integer = d.GetChars(SocketDataBuffer, 0, iRx, chars, 0)

sSocketMessage = New System.String(chars)

end sub



Answer this question

Getting truncated socket bytes

  • Groenewald

    I observed something interesting...... I wrote the client in VB.net using Socket class and wrote the same amount of data that I was writing earlier and I started recieving the whole data in one go i-e with one BeginRecieve.

    Then I tried sending the same amount of data with the client I was using earlier and ran into same issues mentioned in my previous messages. The client is written in VB6 and uses winsock.


    I have this

    Private result As IAsyncResult

    result = soc.BeginReceive(SocketDataBuffer, 0, SocketDataBuffer.Length, SocketFlags.None, SocketpfnCallBack, Nothing)

    and result.IsComplete shows "True" and  I still receive trucated data.

    and no matter how many times I do BeginRecieve I end up getting same number of bytes when I do EndRecieve()

    The clinet has to be in VB6 :(

    Any ideas


  • danglen

    I think I already answered this. You can *NEVER* depend on the behavior you are seeing. TCP does not guarantee one time delivery.

  • Dido44538

    Well thats the only way really.
    The issue with using raw tcp stream is that you have to use some kind of protocol to determine the data boundaries

  • Eric-Jan

    Presumably the data you're receiving is in a pre-agreed format, is there some kind of marker to indicate the end of the data e.g. in an XML document the end root node, double CrLf character, etc.  If so you can check for the existence of this in your BeginReceive callback, if you find it you're done otherwise call BeginReceive again.

    This may not be the best way but it's what I've used in the past and it works fine.

    Regards,

    Colin


  • Finny

    You need to call beginreceive again from the Receive Callback - until you get all the data or

    get 0 bytes. Don't expect that all data will arrive at once. Data can in theory arrive one byte at a time :-)



  • manutdp

    Thanks,

    But this leads to another question...How to find out in receiver callback that all data is recieved

    In Receiver Call back function

    Private Sub SocketOnDataRcvd(ByVal asyn As IAsyncResult)

    I get async object and it has a property .IsComplete that tells whether the operation is completed ot not.

    I tried doing this

    while Not async.IsComplete
       BeginRecieve(...)
    End while

    but async.IsComplete is always true. So I again recieve truncated message as the loop never runs. Another way of knowing is to do

    while bytesReceived > 0

    bytesReceived = workerSocket.EndReceive(asyn)
    workerSocket.BeingReceive()

    End while

    but you can call EndRecieve only once for a socket..so that trick also does'nt work.
    What I ended up doing In Reciever callback is this

    result = workerSocket.BeginReceive(SocketDataBuffer, iRx, (SocketDataBuffer.Length), SocketFlags.None, Nothing, Nothing)

    result = workerSocket.BeginReceive(SocketDataBuffer, iRx, (SocketDataBuffer.Length), SocketFlags.None, Nothing, Nothing)

    result = workerSocket.BeginReceive(SocketDataBuffer, iRx, (SocketDataBuffer.Length), SocketFlags.None, Nothing, Nothing)

    result = workerSocket.BeginReceive(SocketDataBuffer, iRx, (SocketDataBuffer.Length), SocketFlags.None, Nothing, Nothing)

    result = workerSocket.BeginReceive(SocketDataBuffer, iRx, (SocketDataBuffer.Length), SocketFlags.None, Nothing, Nothing)


    which is obviously a very bad way....

    Any ideas


     


  • de_henny

    With TCP there is no gaurantee a call to receive will provide all the data the client has sent.  You have to continually call receive( ) until it returns with a value of 0.



  • Getting truncated socket bytes