Van T 2015-09-17 10:41 采纳率: 0%
浏览 2011
已结题

C# Socket 移动端数据丢失?

事情是这样的:在使用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条回答

  • 微wx笑 Java领域优质创作者 2015-09-17 13:20
    关注

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

    评论

报告相同问题?

悬赏问题

  • ¥15 (希望可以解决问题)ma和mb文件无法正常打开,打开后是空白,但是有正常内存占用,但可以在打开Maya应用程序后打开场景ma和mb格式。
  • ¥20 ML307A在使用AT命令连接EMQX平台的MQTT时被拒绝
  • ¥20 腾讯企业邮箱邮件可以恢复么
  • ¥15 有人知道怎么将自己的迁移策略布到edgecloudsim上使用吗?
  • ¥15 错误 LNK2001 无法解析的外部符号
  • ¥50 安装pyaudiokits失败
  • ¥15 计组这些题应该咋做呀
  • ¥60 更换迈创SOL6M4AE卡的时候,驱动要重新装才能使用,怎么解决?
  • ¥15 让node服务器有自动加载文件的功能
  • ¥15 jmeter脚本回放有的是对的有的是错的