TCP server truncate readed message from networkstream

37 views Asked by At

I have implemented a TCP listener like this:

Using client As TcpClient = _server.AcceptTcpClient()

                Threading.ThreadPool.QueueUserWorkItem(AddressOf NewClient)

                Using ns As NetworkStream = client.GetStream()

                    While ns.DataAvailable

                        Dim toReceive(100000) As Byte

                        Dim length As Integer = ns.Read(toReceive, 0, toReceive.Length)

                        If length > My.Settings.minLenghtForSuccess Then
                            Dim text As String = Encoding.UTF8.GetString(toReceive, 0, length)
                            text = "{" & text.Split("{")(1)
                            Dim jsonObj As Object = Newtonsoft.Json.JsonConvert.DeserializeObject(text)
                            Dim ipOrigine As String = ""
                            Dim dispositivoOrigine As String = ""
                            Dim canaleOrigine As String = ""
                            Dim targa As String = ""
                            Dim frontespizio = jsonObj("data")(0)
                            ipOrigine = frontespizio("IPAddress")
                            dispositivoOrigine = frontespizio("DeviceName")
                            canaleOrigine = frontespizio("ChannelName")
                            targa = frontespizio("PicData")(0)("PlateInfo")(0)("SnapId")

                        End If
                        'Console.WriteLine(text)
                        'Console.WriteLine()

                        'Dim toSend() As Byte = Encoding.ASCII.GetBytes("Message Received...")

                        'ns.Write(toSend, 0, toSend.Length)

                    End While

                End Using

            End Using

When it receive a message from the client it gets truncated and I don't know why. I think it's for toReceive(100000) var. How can I solve this? My incoming message is something like:

POST /API/AlarmEvent/EventPush

HTTP/1.1 Host: 192.168.2.103:123

Accept: /

Content-Type: application/json;charset=UTF-8

Content-Length: 106438

{"result":"success","data":{"EventType":"LPD","EventTime":"2015-1-15 9:53:39","EventAction":"start","ChannelName":"PERGENOVA","DeviceName":"BS-IPT4704G3MZ+","IPAddress":"192.168.2.168","MacAddress":"00-23-63-92-25-47","PicData":{"PlateInfo":[{"Id":"","GrpId":3,"SnapId":"AH234MG","Type":10,"StrChn":"CH1","StartTime":1421315612,"EndTime":1421315656,"Chn":0,"Sex":0,"PlateColor":0,"CarBrand":"","CarType":"","Owner":"","IdCode":"","Job":"","Phone":"","Domicile":"","Remark":"","PlateImg":"/9j/4AAQSkZJRgABAQIAdgB2AAD/7wAPAAAAAAAAAAAAAAAAAP/bAEMAAwICAwICAwMDAwQDAwQFCAUFBAQFCgcHBggMCgwMCwoLCw0OEhANDhEOCwsQFhARExQVFRUMDxcYFhQYEhQVFP/bAEMBAwQEBQQFCQUFCRQNCw0UFB="}]}}}

  • PlateImg is very long, over 100000 byte and its lenght is not fixed
1

There are 1 answers

0
Polarcode On BEST ANSWER

It could be due to the fixed size of the toReceive buffer. you initialized toReceive with a fixed size of 100,000 bytes, if the incoming message is larger than that, it will get truncated as you observed.

Try using a dynamic buffer instead.

e.g.

Using client As TcpClient = _server.AcceptTcpClient()
    Threading.ThreadPool.QueueUserWorkItem(AddressOf NewClient)

    Using ns As NetworkStream = client.GetStream()
        Dim buffer As New MemoryStream() ' Use MemoryStream as a dynamic buffer

        Dim bytesRead As Integer
        Dim receiveBuffer(4096) As Byte ' Buffer to read incoming data in chunks

        Do
            bytesRead = ns.Read(receiveBuffer, 0, receiveBuffer.Length)
            If bytesRead > 0 Then
                buffer.Write(receiveBuffer, 0, bytesRead)
            End If
        Loop While bytesRead > 0

        buffer.Seek(0, SeekOrigin.Begin) ' Reset the position of the MemoryStream

        Dim receivedData(buffer.Length) As Byte
        buffer.Read(receivedData, 0, receivedData.Length)

        ' Now you have the complete message in the receivedData array as bytes.

        Dim text As String = Encoding.UTF8.GetString(receivedData)
        ' Rest of your code to process the message...

    End Using
End Using

Using MemoryStream as dynamic buffer, you can read the incoming data in chunks (4096 bytes in this case) and append it to the buffer until there is no more data to read. Then, you can convert the MemoryStream content to a byte array and proceed with processing the received message.