C# Socket 移动端数据丢失? 20C

事情是这样的:在使用unity开发手机应用,服务器端下发**1435**长度的char数组。然而手机App只收到**1428**个字节。
奇怪的是在**电脑**上收到的消息长度是1435(正确)。
以下是我的测试:
①切换手机的网络(无线1):收到**1428**(每次都是1428)
②切换手机的网络(无线2):收到**1300**(每次都是1300)
③切换手机的网络(无线3):收到**1260**(每次都是1260)
④换成平板测试:测试结果如①②③,说明这个不是设备的问题。

以下为特定网络下的测试结果:
①服务器端下发1435个字节,手机只能收到1260个字节
②服务器端下发1261个字节,手机只能收到1260个字节
③服务器端下发1260个字节,手机收到1260个字节
④服务器端下发1259个字节,手机收到1259个字节。

 public class StateObject
{
    // Client socket.
    public Socket workSocket = null;
    // Size of receive buffer.
    public const int BufferSize = 2048;
    // Receive buffer.
    public byte[] buffer = new byte[BufferSize];
    // Received data string.
    public StringBuilder sb = new StringBuilder();
    public byte[] recieveDatas = new byte[]{};
}
public delegate void InceptData(byte[] getBytes);

public class TCPClient
{
    public string TCPserverName = "name";
    public string TCPserverIP = "自己的IP地址";
    public int TCPserverPort = 1111;
    public Socket clientSocket;
    public InceptData recievet;

    public int charSize = 0;
    int count = 0;

    public TCPClient()
    {
        SocketConnect();
    }
    public TCPClient(string Ip, int Port)
    {
        this.TCPserverIP = Ip;
        this.TCPserverPort = Port;
        SocketConnect();
    }

    public  void SocketConnect()
    {
        IPEndPoint ipe = new IPEndPoint(IPAddress.Parse(TCPserverIP), TCPserverPort);  
        clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        try
        {
            IAsyncResult result = clientSocket.BeginConnect(ipe, new AsyncCallback(connectCallback), clientSocket);
        } catch (Exception e)
        {
            Debug.LogException(e);
        }
    }

    private void connectCallback(IAsyncResult asyncConnect)
    {
        receive();
    }
    public void Send(byte[] sendbytes)
    {
        if (clientSocket == null)
            return;
        if (!clientSocket.Connected)
        {
            clientSocket.Close();
            return;
        }
        try
        {
            IAsyncResult asyncSend = clientSocket.BeginSend(sendbytes, 0, sendbytes.Length, SocketFlags.None, new AsyncCallback(sendCallback), clientSocket);

        } catch (System.Exception e)
        {
        }
    }
    private void sendCallback(IAsyncResult asyncSend)
    {
    }

    public void receive()
    {
        try
        {
            StateObject so = new StateObject();
            so.workSocket = clientSocket;
            //第一次读取数据的总长度
            clientSocket.BeginReceive(so.buffer, 0, prefixSize, 0, new AsyncCallback(receivedCallback), so);
        } catch (System.Exception e)
        {
            Debug.Log(e.ToString());
            clientSocket.Close();
        }
    }
    //字符串长度标志
    public  int prefixSize = 4;
    public MemoryStream receiveData = new MemoryStream();
    public int curPrefix = 0;//需要读取的数据总长度
    public void receivedCallback(IAsyncResult ar)
    {
        receiveData = new MemoryStream();
        try
        {
            StateObject so = (StateObject)ar.AsyncState;
            Socket client = so.workSocket;
            int readSize = client.EndReceive(ar);
            //结束读取、返回已读取的缓冲区里的字节数组长度
            //将每次读取的数据、写入内存流里
            this.charSize = readSize;
            count++;
            if (readSize > 0)
            {
                receiveData.Write(so.buffer, 0, readSize);
                receiveData.Position = 0;
                byte[] presixBytes = new byte[prefixSize];
                receiveData.Read(presixBytes, 0, prefixSize);

                //--------解析出该消息总字节的长度
                curPrefix = 0;
                foreach (byte a in presixBytes)
                {
                    string s = a.ToString();
                    curPrefix = curPrefix * 256 + int.Parse(s);
                }
                //解析正文
                byte[] datas = new byte[curPrefix - 4];
                receiveData.Read(datas, 0, datas.Length);
                receiveDataLoad(datas);
            }
            //继续接收下次游戏
            client.BeginReceive(so.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(receivedCallback), so);


        } catch (System.Exception e)
        {
            Closed();
        }
    }
    private void receiveDataLoad(byte[]  bytes)
    {
        byte[] getByte = new byte[bytes.Length];
        System.Array.Copy(bytes, 0, getByte, 0, bytes.Length);
        recievet(getByte);
    }

    public void Closed()
    {
        try
        {
            if (clientSocket != null && clientSocket.Connected)
            {
                clientSocket.Shutdown(SocketShutdown.Both);
                clientSocket.Close();
            }
            clientSocket = null;
        } catch (System.Exception e)
        {
            Debug.Log(e);
            clientSocket.Close();
            clientSocket = null;
        }
    }
}

若有解惑,不胜感激。

1个回答

把发送的包长度降到1000或500以内试试;

testcs_dn
微wx笑 回复Van T: 嗯,按理说包长越界了应该会分包的吧,不应该出现数据丢失。
4 年多之前 回复
h570768995
Van T 在特定的网络下,上述数值为临界点(1428,1300,1260),即服务器下发的字节数小于这些数值时,不会出现丢包情况。
4 年多之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问