Home Upgrade Search Memberlist Extras Hacker Tools Award Goals Help Wiki Contact

.NET 

Async Sockets Receive / Buffer Issue (Stream data)

I'm trying to send data to the server consistently without pause in a loop, however, when I do so the buffer seems to become offset, and doesn't contain the "expected" packet header and thus fails to read the bytes. I'm fairly stumped on how to fix this issue. If anyone knows what I'm doing wrong please let me know, and any examples would be great. I've not been able to find an answer yet.

The exact error is when the StreamWindow routine begins, shortly after, the stream of data in the receive buffer will contain half of the old sent packet and half of a new packet again as explained above making it so I'm unable to read the "header" bytes of the packet to determine what to do.

Hope someone can help.

SocketObject
Code
 Public Class SocketObject
       Public Socket As Socket
       Public Buffer As Byte()
       Public Sub New(ByVal Sckt As Socket, ByVal Bffer As Byte())
           Me.Socket = Sckt
           Me.Buffer = Bffer
       End Sub
   End Class

The RecieveCallback
Code
Public Sub ReceivedCallback(ByVal Result As IAsyncResult)

       Dim SocketObject As SocketObject = CType(Result.AsyncState, SocketObject)

       Dim SocketError As SocketError
       Dim BufferSize As Integer = SocketObject.Socket.EndReceive(Result, SocketError)

       If SocketError.Equals(SocketError.Success) Then
           Dim Packet(BufferSize) As Byte
           Buffer.BlockCopy(SocketObject.Buffer, 0, Packet, 0, BufferSize)

           HandlePacket(Packet)

           If SocketObject.Socket.Connected Then
               ReDim SocketObject.Buffer(ServerBufferSize)
               SocketObject.Socket.BeginReceive(SocketObject.Buffer, 0, SocketObject.Buffer.Length, SocketFlags.None, New AsyncCallback(AddressOf ReceivedCallback), SocketObject)
           Else
               SocketObject.Socket.Close()
           End If

       ElseIf SocketError.Equals(SocketError.ConnectionRefused) Then
           'User Disconnected
       ElseIf SocketError.Equals(SocketError.ConnectionAborted) Then
           'User Disconnected
       ElseIf SocketError.Equals(SocketError.ConnectionReset) Then
           'User Disconnected
       End If
   End Sub

Send Loop
Code
Public Sub StreamLoop(ByVal ChunkDelay As Integer)
       While Streaming AndAlso ClientSocket.Connected
           Dim Image As Image = TakeWindowScreenshot(GetCaption)
           Dim ImageBytes As Byte() = ConvertImageToBytes(Image)
           Dim CompressedBytes As Byte() = Compress(ImageBytes)
           SendChunkedPacket(ClientSocket, 200, CompressedBytes)
           SetLabelText(LblSentLength, String.Format("Length: {0}", ImageBytes.Length.ToString("N0")))
           System.Threading.Thread.Sleep(ChunkDelay)
       End While
   End Sub
You are reading from a stream. That means that you
1) Might not get the entire packet from just 1 read. You will just get whatever your system has received to that point.
2) You might get a bit of the next packet tacked onto the end of the previous one.

Id say that the reason for it looking like the buffer has been offset is because of reason 2.

Read the first byte, determine the size of the packet, then read x ammout of bytes that you need after that. dont process the data untill you have ensured that you have all the data you need.
Lotta blood to let, peace to make, give a fuk about a check
(Jul 3, 2019 12:28 AM)BahNahNah Wrote:  You are reading from a stream. That means that you
1) Might not get the entire packet from just 1 read. You will just get whatever your system has received to that point.
2) You might get a bit of the next packet tacked onto the end of the previous one.

Id say that the reason for it looking like the buffer has been offset is because of reason 2.

Read the first byte, determine the size of the packet, then read x ammout of bytes that you need after that. dont process the data untill you have ensured that you have all the data you need.

Thanks for the information, however, I currently append the length of the packet or data to be received to the first 2 bytes of the packet (or bytes) sent. However, I'm unsure on how to do what you've said. It's unclear to me how to loop in the subroutine getting all of the bytes needed. I can get the total bytes that must be read, but again, it's unclear to me how I'm supposed to prevent the ReceivedCallback routine to pause and read.

In my attempts, I tried this, however, to no avail.

Code
Dim Packet(BufferSize) As Byte
            Buffer.BlockCopy(SocketObject.Buffer, 0, Packet, 0, BufferSize)

            Dim BytesToRead As Integer = BitConverter.ToUInt16(Packet, 0) - 2
            Dim BytesRead As Integer = 0
            Dim ByteOffset As Integer = 2 + BytesRead

            While BytesToRead > 0
                Dim ReadBytes As Integer = SocketObject.Socket.Receive(Packet, ByteOffset, BytesToRead, SocketFlags.None)
                BytesRead += ReadBytes
                BytesToRead -= BytesRead
            End While

            HandlePacket(Packet)

However, this just rewrites my Array after the first two bytes.
Can you show the code for the SendChunkMethod? And did you check if the 2 bytes from the packet header are matching to the bytes when you send them?
The reason your code isnt working is because you are creating your "Packet" buffer locally every time.

I dont have a IDE at the moment but heres a rough idea
Code
int bytesRecieved = 0;
byte[] currentPacket;

private void RecieveBytes(int num){
    currentPacket = new byte[num];
    
    SocketError SE;
    conn.BeginReceive(currentPacket, 0, currentPacket.Length, SocketFlags.None, out SE, OnDataRecieved, null);

}

private void OnDataRecieved(IAsyncResult AR) {
    SocketError SE = SocketError.SocketError;
    int bytes = conn.EndReceive(AR, out SE);
    bytesRecieved += bytes;
    
    if(bytesRecieved < currentPacket.Length){
        int bytesLeft = currentPacket.Length - bytesRecieved;
        conn.BeginReceive(currentPacket, bytesRecieved, bytesLeft, SocketFlags.None, out SE, OnDataRecieved, null);
    }else{
        //Handle Data
    }
}
Lotta blood to let, peace to make, give a fuk about a check
(Jul 4, 2019 12:04 AM)BahNahNah Wrote:  The reason your code isnt working is because you are creating your "Packet" buffer locally every time.

I dont have a IDE at the moment but heres a rough idea
Code
int bytesRecieved = 0;
byte[] currentPacket;

private void RecieveBytes(int num){
currentPacket = new byte[num];

SocketError SE;
   conn.BeginReceive(currentPacket, 0, currentPacket.Length, SocketFlags.None, out SE, OnDataRecieved, null);

}

private void OnDataRecieved(IAsyncResult AR) {
SocketError SE = SocketError.SocketError;
   int bytes = conn.EndReceive(AR, out SE);
bytesRecieved += bytes;

if(bytesRecieved < currentPacket.Length){
int bytesLeft = currentPacket.Length - bytesRecieved;
conn.BeginReceive(currentPacket, bytesRecieved, bytesLeft, SocketFlags.None, out SE, OnDataRecieved, null);
}else{
//Handle Data
}
}

Thank you, I'll try something like that later when I have time. My approach was going to be, and most likely still will be is to save the BufferLength (bytes left to buffer/read) per SocketObject. Each time I read, I will read the according amount of total pixels in the entire packet. Then, after adding the bytes into an array, I will have the remainder of unread bytes (if there are any), and thus, the first two unread pixels will be the PacketLength, rereading as I would before.


Possibly Related Threads...
Thread / Author Replies Views Last Post
[.NET] by ahmet1257Mar 10, 2022 09:51 AM 2 228 Mar 10, 2022 09:51 AM
Last Post: benio2
[C#] by LookdadonMar 7, 2022 01:38 PM 7 266 Mar 7, 2022 01:38 PM
Last Post: Lookdadon
[Python] by DoomslayerMar 16, 2021 08:19 AM 9 339 Mar 16, 2021 08:19 AM
Last Post: synchronizing