客户端与服务端连接后, 若收到的信息大与buffersize,这里为1024,可以循环读出,如下面的程序:
         string msg="hello";
         StreamWriter FileData = new StreamWriter(fileurl);
         TcpClient tcpclnt = new TcpClient();
         tcpclnt.Connect(IPAddress.Parse(Publec_Class.ServerIP), Convert.ToInt16(Publec_Class.ServerPort)); 
         Stream stm = tcpclnt.GetStream();
         UTF8Encoding asen = new UTF8Encoding();
         byte[] ba = asen.GetBytes(msg);
         stm.Write(ba, 0, ba.Length);
         byte[] bb = new byte[1024];
         int k = stm.Read(bb, 0, 1024);
         while (k > 0)
           {
              string Str = System.Text.UTF8Encoding.UTF8.GetString(bb, 0, k);
              FileData.Write(Str);
              k = stm.Read(bb, 0, 1024);
           }
         FileData.Close();
但是,如果客户端发送的信息大于1024,在服务端怎么读呢?
下面是我的服务端程序:
                IPAddress myip = IPAddress.Parse(Publec_Class.myIP);
                int myport = Convert.ToInt16(Publec_Class.myPort);  
                IPEndPoint myipendpoint = new IPEndPoint(myip, myport);
                myListener = new TcpListener(myipendpoint);
                myListener.Start();
                while (serverRun)
                {
                    Socket myQS;
                    myQS = myListener.AcceptSocket();
                    string RemoteEndPoint = myQS.RemoteEndPoint.ToString();
                    IPAddress remoteip = ((IPEndPoint)myQS.RemoteEndPoint).Address;
                    int remoteport = ((IPEndPoint)myQS.RemoteEndPoint).Port;
                    Byte[] Stream = new Byte[1024];
                    myQS.Receive(Stream);
                    string save = System.Text.Encoding.UTF8.GetString(Stream);
                    ss = save.Split('|'); ;
                    switch (ss[0])
                    {
                        case "FlagNowChange":
                             ......
                            break;
                        default://发送错误参数
                            break;
                    }
                    myQS.Close();
                }
好象只有客户端的tcpclnt.GetStream()可以读取长度不定的信息,在服务端我只能读规定长度的信息,总不能把buffersize设得很大吧,那样也太浪费资源了,我该怎么办???

解决方案 »

  1.   

    我只看了你最后一句话.你这个问题,其实不是tcp/ip上边做的,而是要你自己处理每次发送和接受流的协议,就像包的结构一样...
    你要自己写个解析的模块来处理这类问题
      

  2.   

    好象只有客户端的tcpclnt.GetStream()可以读取长度不定的信息,在服务端我只能读规定长度的信息,总不能把buffersize设得很大吧,那样也太浪费资源了,我该怎么办??? 
    你根本不用去操心这个问题
    首先一点,tcp/ip协议已经解决了发送包大小的问题,可以查阅一下
    第二点,就算你把服务器端的buff设置成10bit也可以正常接收,不存在你说的那个问题
    第三点,你把buffsize设的再大也不会有所谓浪费资源的情况。消耗cpu时间的只在于初始化那个buff,基本忽略不计!
      

  3.   

    谢谢各位
    我的客户端可能向服务端传几百M的数据,总觉得把buff设得太大不妥,因为我大量的数据都是很小,在实际网络中,小包优先,所以不想把数据包弄大,不知我的概念有没有错?如果照我的初衷,有没有办法?
      

  4.   

    对,可以自己定义个协议,比如说在发送一条字符串前面加上
    [length=1024]字符串
      

  5.   

    服务器端一样可以循环读取的,虽然使用的是Socket,但其实和TcpClient效果一样。如果需要高效的Socket通讯,可以将客户端也改为Socket,使用Socket类的xxxAsync方法,那个方法可以一次性分配内存,重用数据缓存,大量I/O操作的情况下,效率最高。
      

  6.   

    http://blog.csdn.net/tigerii/archive/2009/08/18/4460292.aspx
      

  7.   

    再加一个循环
    http://cid-181e9b2001d6aa91.spaces.live.com/blog/cns!181E9B2001D6AA91!395.entry
    每当缓冲区满了以后,继续接收剩下的
      

  8.   

    按照你的那种循环读取的思路写法,其实服务器端跟客户端是一样的:MemoryStream memo=new MemoryStream();
    int k=0;
    do
    {
        Byte[] Stream = new Byte[1024];   //这里起名Stream实在是不明智
        k=myQS.Receive(Stream); 
        memo.Weite(Stream,0,k);
    }while(k==1024);
    如果发送端以1000个字节为一块buffer来发送信息,而接收端以1024个字节为一个buffer来就收信息,那么接收端可能只接收到1000个字节吗?不可能。实际上至少对tcp来说,发送端关闭了Stream的时候,接收端才开始接收数据,因此服务器端的缓冲区大小根本就跟发送端没有任何关系。
    你写的程序只能作为一个了解编程的基础。我从来不在服务器端写这类同步处理程序,这个效能实在是低下得很。按照异步处理的思路,服务器端得到一个AcceptSocket()之后,它在接受和解析处理消息的时候其它的AcceptSocket完全可以并行执行。同时,异步处理也可以使用Windows完成端口、操作系统特别优化的线程池等等机制,而不是使用程序员自己创建的线程。
      

  9.   

    memo.Weite(Stream,0,k)  -->  memo.Write(Stream,0,k); 
    之后,你就可以从memo.ToArray()来读取接收到的所有信息。
    当你传递100M的内容的时,你应该断点续传,这跟单个消息的组织没有关系。
      

  10.   

    Sorry,上面写错了一句,并不是在关闭Stream的时候服务器端读。当然,如果要处理复杂一点的功能,接收端往往一边读取数据一边解析,例如处理符合http协议消息。
      

  11.   

    tcp应该先发一个长度,接收方先收这个长度,再接收数据,当接受的数据长度达到之前的长度后结束。
    这样做的原因是解决tcp粘包现象