0

I have a problem with a socket server receiving first 2 bytes from the client correctly and the rest are just null bytes, and the packet length is correct as well,

Client send function:

internal void Send(byte[] _data) {
        if (!IsValid()) return;
        try {
            ushort wrLenBuf = (ushort)_data.Length;
            byte[] data = new byte[2 + wrLenBuf];
            BinaryPrimitives.WriteUInt16LittleEndian(data, wrLenBuf);
            xMemUtils.MemCopy2(_data, 0, ref data, 2);

            string s = "";
            foreach (var b in _data) s += b + " ";
            Console.WriteLine(s);

            stream.WriteAsync(data, 0, wrLenBuf + 2);
        } catch (Exception e) {
            Console.WriteLine(e.ToString());
            Close();
        }
    }

Which produces the output: 2 4 8 48 48 48 48 48 48 48 48 48 48 48 48 which is the correct bytes of 15 length.

The server ReceivePacket function:

        int totBytesRead;
        private async void RcvPkt(ushort pktSz) {
            Console.WriteLine("PktSz: " + pktSz);
            totBytesRead = 0;
            byte[] buf = new byte[pktSz];
            while (totBytesRead < pktSz) {
                readLen = await stream.ReadAsync(buf.AsMemory(totBytesRead, pktSz - totBytesRead));
                if (readLen == 0) {
                    Close();
                    return;
                }
                totBytesRead += readLen;
                Console.WriteLine("TotalBytesRead: " + totBytesRead);
            }
            string s = "RcvArr: ";
            foreach (var b in buf) s += b + " ";
            Console.WriteLine(s);
            //Console.WriteLine("PSz: " + pktSz + " BfLen: " + buf.Length + " | " + Encoding.UTF8.GetString(buf, 0, pktSz));
            //Packet.Handler.thiz.Handle(this, buf);
            RcvPktSz();
        }

Output:

PktSz: 15
TotalBytesRead: 15
RcvArr: 2 4 0 0 0 0 0 0 0 0 0 0 0 0 0

I tried with this 15byte length array, 41byte length array, both receive full packet but only the first 2 bytes correctly and the rest are null bytes \0.

That's from client to server, on the other hand when sending a string from the server to client it gets it correctly.

I would appreciate anyone helping or having any idea of what's goin wrong here.

xYuri
  • 369
  • 2
  • 17
  • 1
    `xMemUtils.MemCopy2(_data, 0, ref data, 2);` Does that last `2` mean 2 bytes? – 001 Sep 07 '22 at 00:39
  • @JohnnyMopp yes that's the packet length which is received by the method `RcvPktSz()` and passed to `RcvPkt(ushort)` afterwards which is 15 bytes in this case. – xYuri Sep 07 '22 at 00:41
  • `stream.WriteAsync(data, 0, wrLenBuf + 2);` should be `await stream.WriteAsync(data, 0, wrLenBuf + 2);` Also the use of `async void` is suspicious, you cannot await these functions so the stream may get closed or written to again before it's finished – Charlieface Sep 07 '22 at 00:58
  • 1
    You're checking the value of `_data`, not `data`. Please verify that the bytes you're sending are correct. TCP/IP has checksums and retransmissions built-in to prevent almost all data corruption. – Stephen Cleary Sep 07 '22 at 01:41
  • @Charlieface ah, makes sense to `await` for `WriteAsync`, and for `async void` i just marked it async to be able to block the loop to get the packet fully before continuing because i split it as packets, receiving exact packet size each time. – xYuri Sep 07 '22 at 02:01
  • 2
    Well that doesn't work, it should be `async Task` not `async void` and then you `await` all the way up – Charlieface Sep 07 '22 at 02:02
  • @StephenCleary yes you're right, the actual byte array sent was incorrect, the copy function only copies the first 2 bytes of the `_data` array, thank you. please mention it in an answer so and I will accept it. – xYuri Sep 07 '22 at 02:06
  • @Charlieface so I have to await from the main calling function, or run it inside `Task.Run()`? – xYuri Sep 07 '22 at 02:08
  • 1
    Correct. See https://stackoverflow.com/a/29809054/14868997 and others. `async void` belongs in only one place: an event handler coming off a button click etc. Do not use `.Result` or `GetResult()` as you may deadlock – Charlieface Sep 07 '22 at 02:12

0 Answers0