none
使用Socket.ReceiveFrom如何一次性收取socket缓存数据 RRS feed

  • 问题

  • 使用如下代码,发送UDP数据:
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Net;
    using System.Net.Sockets;
    using System.IO;
    
    namespace UDPClient
    {
      class Program
      {
        static void Main(string[] args)
        {
          FileStream FS=new FileStream("c:\\ttt.dat",FileMode.Open);
          BinaryReader BR=new BinaryReader(FS,Encoding.Default);
    
    
          byte[] data = new byte[1024];
          string input, stringData;
    
          //构建TCP 服务器
    
    
          //设置服务IP,设置TCP端口号
          IPEndPoint ipep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8001);
    
          //定义网络类型,数据连接类型和网络协议UDP
          Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
    
          server.Bind(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9000));
    
          while (FS.Position<FS.Length)
          {
            if (FS.Length - FS.Position > 100)
              data = BR.ReadBytes(100);
            else
              data = BR.ReadBytes((int)(FS.Length - FS.Position));
            server.SendTo(data, data.Length, SocketFlags.None, ipep);
          }
    
          server.Close();
        }
    
      }
    }
    
    
    
    使用如下代码,接收UDP数据:
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Net;
    using System.Net.Sockets;
    
    namespace UDP
    {
      class Program
      {
        static void Main(string[] args)
        {
          int recv;
          byte[] data;
    
          //构建TCP 服务器
    
          //得到本机IP,设置TCP端口号     
          IPEndPoint ipep = new IPEndPoint(IPAddress.Any, 8001);
          Socket newsock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
    
          //绑定网络地址
          newsock.Bind(ipep);
    
          IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
          EndPoint Remote = (EndPoint)(sender);
    
    
          while (true)
          {
            if (newsock.Available == 0)
            {
              System.Threading.Thread.Sleep(1);
              continue;
            }
            int bufferSize = newsock.Available;
            data = new byte[bufferSize];
    
            recv = newsock.ReceiveFrom(data,bufferSize ,SocketFlags.None, ref Remote);
          }
        }
    
      }
    }
    
    想一次性把socket缓存中已有的数据都收完,但是发现不行,指定了bufferSize也不行,接收端的recv始终等于100,和发端每次发送的数据一样,即使newsock.Available=1000,每次也只收100字节,要分10此才能把数据收完,这是为什么呢?该如何解决?谢谢!
    2010年5月13日 16:22

答案

  • ---
    
    recv = newsock.ReceiveFrom(data,bufferSize ,SocketFlags.None, ref Remote);
    
    -----
    
    你对 newsock.Available的理解有问题 
    你可以从这里去了解
     http://technet.microsoft.com/zh-cn/library/system.net.sockets.socket.available(zh-tw,VS.80).aspx
    指的是已从网络接收的可供读取的数据
    
    所以这个int bufferSize =1024;
    比如1024是需要你手动设置的 
    
    ReciveFrom应该使用这个重载函数
    
    int len=newsock.ReceiveFrom(data,ref Remote);
    然后你可以在while外面定义一个变量 string strAsciiData="";
    
    在每次ReciveFrom执行后面
    strAsciiData+=Encoding.ASCII.GetString(data,0,len);
    
    这样就可以了

     

    • 已编辑 用心 2010年5月14日 3:55 输入有错误
    • 已标记为答案 KeFang Chen 2010年5月17日 4:10
    2010年5月14日 3:54