Android Tcp Socket Problem

hi everyone,

*I finished a server / client project to send and receive packets. The project works fine on the computer, but android only sends 3-4 large packages and never sends after them.No problem with small packets on android. There is no problem getting the server out of the box, but the android is having trouble sending large packets.I can give you skype if you can help. I share my code down there and I’m waiting for help. Thx…

client:

    void SendWhole(Socket sock, IPacket packet)
    {
        var stream = new MemoryStream();
        var writer = new BinaryWriter(stream);
        
        byte[] payload = packet.ToBytes();
        writer.Write((short)packet.GetOpcode());
        writer.Write(payload.Length);
        writer.Write(payload);
        
        byte[] bufferCopy = new byte[stream.ToArray().Length];
        System.Buffer.BlockCopy(stream.ToArray(), 0, bufferCopy, 0, bufferCopy.Length);
        
        sock.Send(bufferCopy,0,bufferCopy.Length ,SocketFlags.None );
    }`

my server recieve method:

    private void ProcessReceive(SocketAsyncEventArgs e)
    {
        var state = (StateObject)e.UserToken;
        
        // Check if the remote host closed the connection
        if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success)
        {
            // Opcode not set -> Header has not been parsed yet
            if (state.Opcode == -1)
            {
                ReadHeader(e);
            }
            else
            {
                ReadBody(e);
            }
        }
        else
        {
            CloseClientSocket(e);
        }
    }
    
    private void ReadHeader(SocketAsyncEventArgs e)
    {
        var state = (StateObject)e.UserToken;
        
        state.TotalBytesRead += e.BytesTransferred;
        
        // If header isn't read fully, read more
        if (state.TotalBytesRead < HeaderLength)
        {
            int missing = HeaderLength - state.TotalBytesRead;
            e.SetBuffer(e.Buffer, e.Offset, missing);
        }
        else
        {
            // Received full header, parse it and read packet body
            state.Opcode = BitConverter.ToInt16(state.Buffer, 0);
            state.PacketDataLength = BitConverter.ToInt32(state.Buffer, 2);
            state.PacketData = new byte[state.PacketDataLength]; // TODO: Hot-Spot, use pooled buffers to avoid GC overhead
            state.TotalBytesRead = 0;
            
            e.SetBuffer(state.PacketData, 0, state.PacketDataLength);
        }
        BeginReceive(e);
    }
    
    private void ReadBody(SocketAsyncEventArgs e)
    {
        var state = (StateObject)e.UserToken;
        Console.WriteLine("GETTED LEGenTH = " + state.PacketData.Length.ToString());
        // Body not received fully, read more
        if (e.BytesTransferred < state.PacketDataLength)
        {
            var missing = state.PacketDataLength - e.BytesTransferred;

            e.SetBuffer(state.PacketData, e.Offset, missing);
            Console.WriteLine("GET DATA CORPUT!");
            //////////////////////////////////////////////////// I GET HERE ON ANDRIOD!////////////////////////////////////
        }
        else
        {
            // Publish packet to business logic (DON'T BLOCK THERE, use worker threads if needed)
            OnPacketReceived(state.Opcode, state.PacketData);
            
            // Don't forget to reset this
            e.SetBuffer(state.Buffer, 0, HeaderLength);
            state.TotalBytesRead = 0;
            state.Opcode = -1;
        }
        
        BeginReceive(e);
        var packet = CreateRandomPacket();
        if (state.ClientSocket.Connected)
            SendWhole(state.ClientSocket, packet);
    }

Your question sounds a bit confusing. The provided code snippet makes it hard to follow what happens, especially your receiving code.

Are you aware of the fact that TCP is a stream protocol and not a packet protocol. Of course the stream is transmitted with one or multiple packets but from the application point of view a TCP connection just provides a data stream. A stream can be splitted (fragmented) across multiple packets however TCP ensures that the data arrives in the right order. The MTU size can vary between different hardware implementations as well as different operating systems. If the data you send + protocol overhead is larger than the MTU size the data need to be splitted.

Receiving code for a TCP connection should always use a buffer where it can append the next data chunk once it arrived. If you plan to send “packets” over a TCP connection you have to manually detect the beginning and end of your packet as TCP is an endless stream of bytes which can arrive at any speed / fragmentation.

Not related to MTU size.

i have this: I do not see a problem when I put a ThreadSleep(50) on the ProcessReceive function. But I do not have to set a ThreadSleep for my fast data transfer. what should I do?