首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > C# >

怎么让byte[]数组大小随Socket的Receive接收内容大小来变化

2012-05-21 
如何让byte[]数组大小随Socket的Receive接收内容大小来变化如题。byte[]数组大小不定长,SOCKET传输总长度不

如何让byte[]数组大小随Socket的Receive接收内容大小来变化
如题。byte[]数组大小不定长,SOCKET传输总长度不定,通过TCP/IP每次只传输500字节,使用异步传输, 总长度有时候是1000,有时候695,有时候1200这样的。主要代码如下:

private void AcceptCallback(IAsyncResult ar)
  {
  mse.Set();
  Socket listen = ar.AsyncState as Socket;
  Socket client = listen.EndAccept(ar); //对每一个侦听的客户端端口信息进行接收和回发
  StateObject so = new StateObject();
  so.ClientSocket = client;
  client.BeginReceive(so.Buffer, 0, StateObject.BUFFER_SIZE, SocketFlags.None, ReceiveCallback, so);  
  mse.WaitOne();  
  }


  private void ReceiveCallback(IAsyncResult ar)
{

StateObject so = ar.AsyncState as StateObject;
int recv=0;
reqeustcount += 1;
recv = so.ClientSocket.EndReceive(ar);

if ((recv > 0))
{
byte[] recvBytes = new byte[recv];
}

so.ClientSocket.BeginReceive(so.Buffer, 0, StateObject.BUFFER_SIZE, SocketFlags.None, ReceiveCallback, so);
}


这段代码其中的“recv”长度每次都是500传输一次。比如第一次传输500,第二次500,第三次500,第四次70之类的算是接收完了。每次都是一段一段的,不能累积。


我应该怎样把这四次结果都存储在一个byte[]数组中呢,还是保存在array[]数组中呢。


谢谢,在线等。

[解决办法]

C# code
/// <summary>        /// 向客户端发送消息        /// </summary>        /// <param name="strMsg"></param>        public void Send(string strMsg)        {            byte[] arrMsg = System.Text.Encoding.UTF8.GetBytes(strMsg);            byte[] arrMsgFinal = new byte[arrMsg.Length+1];            arrMsgFinal[0] = 0;//设置 数据标识位等于0,代表 发送的是 文字            arrMsg.CopyTo(arrMsgFinal, 1);            sokMsg.Send(arrMsgFinal);        }
[解决办法]
下面mToProcess就是你想要的 
C# code
         int nBytesRec = sock.EndReceive(ar);            //如果有接收到数据的话                        if (nBytesRec > 0)            {                //将接收到的数据转个码,顺便转成string型                        string sRecieved = Encoding.GetEncoding("utf-8").GetString(m_byBuff, 0, nBytesRec);                //声明一个字符串,用来存储解析过的字符串                        string m_strLine = "";                //遍历Socket接收到的字符                                /*                               * * 此循环用来调整linux 和 windows在换行上标记的区别                       * * 最后将调整好的字符赋予给 m_strLine                               * */                for (int i = 0; i < nBytesRec; i++)                {                    Char ch = Convert.ToChar(m_byBuff[i]);                    switch (ch)                    {                        case '\r':                            m_strLine += Convert.ToString("\r\n");                            break;                        case '\n':                            break;                        default:                            m_strLine += Convert.ToString(ch);                            break;                    }                }                try                {                    //获得转义后的字符串的长度                           int strLinelen = m_strLine.Length;                    //如果长度为零                                      if (strLinelen == 0)                    {                        //则返回"\r\n" 即回车换行                                  m_strLine = Convert.ToString("\r\n");                    }                    //建立一个流,把接收的信息(转换后的)存进 mToProcess 中                        Byte[] mToProcess = new Byte[strLinelen];                    for (int i = 0; i < strLinelen; i++)                        mToProcess[i] = Convert.ToByte(m_strLine[i]);                    // Process the incoming data                                       //对接收的信息进行处理,包括对传输过来的信息的参数的存取和                         string mOutText = ProcessOptions(mToProcess);                    //解析命令后返回 显示信息(即除掉了控制信息)                                     if (mOutText != "")                        Console.Write(mOutText);                    // Respond to any incoming commands                                       //接收完数据,处理完字符串数据等一系列事物之后,开始回发数据                        RespondToOptions();                }                catch (Exception ex)                {                    throw new Exception("接收数据的时候出错了! " + ex.Message);                }            } 


[解决办法]
最好不要这样:动态变化,就会动态重新分配内存,对应通信程序是个很大负担!内存会不断增加!
一般的做法:定义一个合理的类全局的缓冲区大小!通信程序,一般有通信协议的概念,里面有数据帧的概念,
数据帧有头尾标记,你在接收处理是,根据头尾标记来处理一个完整的帧数据,有可能超过你换成区大小,这是会有多帧数据,组成完整的数据帧。
[解决办法]
其实我也建议楼主放弃 分多次传递的设计。
你在花费很多额外的工作去处理本该一次完成的工作,
可能你的受到某些限制,但是你可以争取去该别这些设置。
[解决办法]
用List<byte>,最后确认完成接收:即到达帧尾,把它一次性转换:

如:
List<byte> bytelist=new List<byte>();
............

byte[] bytearr=bytelist.ToArray();

[解决办法]
TCP接收的都是 Byte数组,你要转码才能看到,发送的是什么数据啊

你要问发送的人是怎么发的,一般不做特殊处理的都是UTF8格式的
[解决办法]
MemoryStream ms = new MemoryStream();

private void AcceptCallback(IAsyncResult ar)
{
mse.Set();
Socket listen = ar.AsyncState as Socket;
Socket client = listen.EndAccept(ar); //对每一个侦听的客户端端口信息进行接收和回发
StateObject so = new StateObject();
so.ClientSocket = client;
client.BeginReceive(so.Buffer, 0, StateObject.BUFFER_SIZE, SocketFlags.None, ReceiveCallback, so);
mse.WaitOne();

ms.Flush();
byte[] received = ms.ToArray();
PrintByteArray(received);
}

private void ReceiveCallback(IAsyncResult ar)
{
StateObject so = ar.AsyncState as StateObject;
int recv = 0;
reqeustcount += 1;
recv = so.ClientSocket.EndReceive(ar);

if ((recv > 0))
{
//byte[] recvBytes = new byte[recv];
ms.Write(so.Buffer, 0, recv);
}

so.ClientSocket.BeginReceive(so.Buffer, 0, StateObject.BUFFER_SIZE, SocketFlags.None, ReceiveCallback, so);
}

热点排行