Socket的接收信息方法Receive的参数是一个byte[]数组,用在存放收到的数据。
byte[]是一个先要定义好的一个对象且具有大小,而收到的信息事先是不知道内容的大小,如果收到的内容的大小超出了byte[]的定义,超出的部分就会失去。
如何解决这个问题,让Receive的结果给一个可变的接收对象呢
我写的代码如下:
byte[] byteMessage=new byte[1000];
try
{
socket.Listen(5);
Socket newSocket=socket.Accept();
newSocket.Receive(byteMessage);
        ...

解决方案 »

  1.   

    Socket的Receive方法有多个重载,你可以定义一个bufferlength.private const int BUFFERLENGTH = 1000;byte[] byteMessage = new byte[BUFFERLENGTH];try
    {
    .....
    newSocket.Receive(byteMessage, BUFFERLENGTH,0);
    .....}
      

  2.   

    常用的处理方式是每次都去判断一下接收到的byteMessage, 如果有内容就继续执行Receive方法。这样循环就可以得到所有内容了。
      

  3.   

    to:dreammaster 关键是你不知道要传送数据的长度是多少啊。如何根据传来的信息得知BUFFERLENGTH长度呢?在网上找到一个Socket.ReceiveBufferSize方法来确定长度,可是C#.net里没有这个方法啊!
      

  4.   

    to:dreammaster  
    常用的处理方式是 每次都去判断一下接收到的byteMessage,   如果有内容就继续执行Receive方法。这样循环就可以得到所有内容了。
    -----------------------------------------------------
    newSocket.Receive(byteMessage); 
    这个方法不是就一次性把信息给接下来了吗,怎么持续接收呢。能给代码吗
      

  5.   

    Receive方法有返回值的吧,表示接收了多少字节,如果小于指定的长度就说明接收完了。
      

  6.   

    一般socket通讯 ,传递的数据都分为2部分,Header+Body;
    Header长度一般固定,我最近做了一个Socket通讯的,头长度24,用4个字节存储总长度;
    你可以根据需要,在Header里预留几个字节存储总长度信息,
    我取得时候先取24字节,然后再取出总长度;
    然后根据总长度,去取Body,Body长度=总长度-Header长度;不知道我说清楚了么
      

  7.   

    这是一个简单的接数据的代码,SocketObject _State = new SocketObject();
                    _State.WorkSocket = _Client;
    //获取头 HEADERSIZE市场量=24
                    byte[] _Header = new byte[HEADERSIZE];
                    byte[] _Body = null;
                    PackageHeader _PackageHeader = new PackageHeader();
                    int _BodyLength = 0;
                    string _ReceiveData = string.Empty;
                    _Client.Receive(_Header, HEADERSIZE, SocketFlags.None);
                    _PackageHeader = DecodeHeader(_Header);
    //根据总长度得到包体长度                
    _BodyLength = int.Parse(_PackageHeader.Total_Length.ToString()) - HEADERSIZE;
                    if (_BodyLength > 0)
                    {
                        _Body = new byte[_BodyLength];
                        _Client.Receive(_Body, _BodyLength, SocketFlags.None);
                        _ReceiveData = Encoding.UTF8.GetString(_Header) + Encoding.UTF8.GetString(_Body);
                    }
      

  8.   

    写个while循环调用Recive方法,直到Recive方法返回的值<=0,即此次Recive操作完毕。
    不可能知道Recive长度的,除非你自己写的发送固定字段。
      

  9.   

    解决:
    不用让byte[]数组大小随Socket的Receive接收的信息内容大小来变化。
    因为可以让Socket的Receive方法不停的执行(即把它放入一个死循环里面)最后再判断一下Receive接收的数据量是否为0来作为停止循环的条件。
    代码如下:
    //得到指定Ip的IP的主机,即可以是外网的IP。通常都用外网的ip来通信
    public static IPAddress GetServerIP(string LocalIP)
    {
    IPHostEntry ieh=Dns.GetHostByAddress(LocalIP);
    return ieh.AddressList[0];
    } private void BeginListen()
    {
    IPAddress ServerIp=GetServerIP(this.txtLocalIP.Text);
    IPEndPoint iep=new IPEndPoint(ServerIp,int.Parse(txtPort.Text)); socket=new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
     
    this.label1.Text=iep.ToString(); socket.Bind(iep);

    while(true)
    {
    try
    {
    string rmsg="";
    socket.Listen(5);
    Socket newSocket=socket.Accept();
    int bytes=0;
    while(true)
    {
    byte[] byteMessage=new byte[10];
    //循环执行,它会从头到尾自动接收数据给存放对象。
    //Receive的返回值是一个接收数据的字节数,必须得到该值,用以控制循环的次数和转换成字符串的字符数。
    bytes=newSocket.Receive(byteMessage);
    //或
    //bytes=newSocket.Receive(byteMessage,byteMessage.Length,0); //控制循环次数
    if(bytes<=0)
    break;
    //用Encoding.GetEncoding("gb2312"); 来写的话字符“@”就显示不正常
    System.Text.Encoding encoding = System.Text.Encoding.UTF8;

    string msg=encoding.GetString(byteMessage,0,bytes); //两种方式都可以,得到去除字符“\0”的有用字符串
    //string msg=encoding.GetString(byteMessage).TrimEnd('\0'); //msg=msg.Split('\0')[0];
    rmsg=rmsg+msg;
    }

    string sTime = DateTime.Now.ToShortTimeString();
    rmsg=sTime+":"+"Message from:"+newSocket.RemoteEndPoint.ToString()+"\r\n"+rmsg+"\r\n"+"\r\n";

    this.txtMessage.Text=this.txtMessage.Text+rmsg;
    }
    catch(SocketException ex)
    {
    this.label1.Text+=ex.ToString();
    }
    }
    }
      

  10.   

    注:
    外面的while循环是让监听方法:BeginListen不停止,即一直监听下去,一般是用一个线程来执行。
    里面的while循环是让Socket的Receive方法不停止接收信息。
      

  11.   

    ReceiveBufferSize
    定义的数组长度偏大