TcpListener接收数据不全?
下面是接收代码的异步类,但是发现接收数据不全,如果发送的数据比较多的话;
protected void AcceptClient(IAsyncResult ar)
         {
             try
             {
                 TcpListener tcpListener = (TcpListener)ar.AsyncState;
                 TcpClient tcpClient = tcpListener.EndAcceptTcpClient(ar);                 
                 NetworkStream networkStream = tcpClient.GetStream();
                 StreamReader streamReader = new StreamReader(networkStream);
                 string content = streamReader.ReadToEnd();
                 rtbxContent.Invoke(new MethodInvoker(delegate
                 {
                     rtbxContent.Text = "";
                     rtbxContent.Text = content;
                 }));                  
                 networkStream.Close();
                 tcpClient.Close();                                      
                 //tcpListener.Stop();
                 tcpListener.BeginAcceptTcpClient(new AsyncCallback(AcceptClient), tcpListener);
                 //这样写也是可以的,只是要等到一个线程结束之后才会开始接收下一个请求
             }
             catch (Exception ex)  
             {
                 MessageBox.Show("出错了: \n" + ex.Message, "错误");
             }              
         }
------解决方案--------------------如果数据量大的话不能只是一次接收,你应该循环接收啊。网上代码有很多呢
------解决方案--------------------怎么可能使用 StreamReader 来判断“结束”呢?通讯是在底层被拆成100多个字节一个小数据包逐步传送的,通讯消息的结束标志是用通讯内容来标记的,就好象开会发言时说“我说完了”来表示发言结束,而不是用0.5秒钟停顿来代表发言结束。
------解决方案--------------------与之相关的,读取 networkStream = tcpClient.GetStream() 中的数据时也应该使用异步 BeginRead 方法,因为即使客户端是一次Send 100K 字节,服务器端也可能需要分50次接收完全,中间有短暂的停顿,这个时间阻塞这去同步Read,比较浪费资源。
你可以使用一个 MemoryStream,将异步读取的数据写到它里边。然后当读取到消息结束时,才取出累积的数据,统一处理。
------解决方案--------------------TCP客户端->
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net.Sockets;
using System.Threading;
namespace TCPClient
{
   public partial class TCPClient : Form
   {
       public TCPClient()
       {
           InitializeComponent();
       }
       TcpClient tc = null;
       Thread td = null;
       private void button1_Click(object sender, EventArgs e)
       {
           tc = new TcpClient();
           tc.Connect("127.0.0.1",10000);
           td = new Thread(new ThreadStart(getmges));
           td.IsBackground = true;
           td.Start();
       }
       NetworkStream ns = null;
       public void getmges()
       {
           ns = tc.GetStream();
           while (true)
           {
               if (ns.DataAvailable)
               {
                   byte[] bt = new byte[1000];
                   ns.Read(bt,0,tc.Available);
                   string str = Encoding.UTF8.GetString(bt);
                   MessageBox.Show(str);
               }
           }  
       }
       private void button2_Click(object sender, EventArgs e)
       {
           string str = textBox1.Text;
           byte[] bt = Encoding.UTF8.GetBytes(str);
           ns = tc.GetStream();
           ns.Write(bt,0,bt.Length);
       }
   }
}