why android only receive 2896 bytes on c# tcp sock

2019-09-02 06:32发布

问题:

c# Use tcp socket Send message to Android:

string data = "my message....";
byte[] msg = Encoding.UTF8.GetBytes(data);
//for example msg Length is 5210 bytes
client.socket.SendBufferSize = 500000;
socket.Send(msg, msg.Length, SocketFlags.None);

Android receive message from c# server-side:

    socket = new Socket(ServerIP, ServerPort);
    socket.setReceiveBufferSize(500000);
    isReceive = true;
    receiveThread = new ReceiveThread(socket);
    receiveThread.start();

private class ReceiveThread extends Thread{
private InputStream inStream = null;
ReceiveThread(Socket socket){
inStream = socket.getInputStream();
}
@Override
public void run(){
while(isReceive){
byte[] buffer = new byte[99999];
try {
//only receive 2896 bytes?
int size = inStream.read(buffer);
} catch (IOException e) {
unConnSocket();
}
}
}
}

why the size only receive 2896 bytes?

回答1:

Your Android code has no way of knowing how many bytes the C# code is sending. inStream.read() is reading only the bytes that are currently available on the socket at that moment. You should have the C# code send the string length before sending the string data, so that the Android code knows how many bytes to expect, eg:

string data = "my message....";
byte[] dataBytes = Encoding.UTF8.GetBytes(data);
int dataLen = IPAddress.HostToNetworkOrder(dataBytes.Length);
byte[] dataLenBytes = BitConverter.GetBytes(dataLen);
socket.Send(dataLenBytes);
socket.Send(dataBytes);

private class ReceiveThread extends Thread
{
    private DataInputStream inStream = null;

    ReceiveThread(Socket socket)
    {
        inStream = new DataInputStream(socket.getInputStream());
    }

    @Override
    public void run()
    {
        while (isReceive)
        {
            try
            {
                String s;
                int size = inStream.readInt();
                if (size > 0)
                {
                    byte[] buffer = new byte[size];
                    inStream.readFully(buffer); 
                    s = new String(buffer, "UTF-8");
                }
                else
                    s = "";

                // use s as needed ...
            }
            catch (IOException e)
            {
                unConnSocket();
            }
        }
    }
}


回答2:

Because TCP is a byte stream protocol and isn't obliged to deliver you more than one byte at a time.

You have to loop.

I quote from Linux man recv(2):

The receive calls normally return any data available, up to the requested amount, rather than waiting for receipt of the full amount requested.