TcpClient的TcpClient.GetStream().Read()读取慢

techie 2017-09-16 08:59:32
我用TcpClient.GetStream().Read()来读取TCP发送的数据,Read()是新建的一个Thread,在Thread中死循环不断的读取TCP的数据,但是我把发送端关了,还能不断更新20秒才能更新完;发送端是一个自制的电路板,发送速度快,而这个PC端接收和处理速度太慢了,如何才能提高TCP在PC端的接收速度?
...全文
1517 7 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
techie 2017-09-21
  • 打赏
  • 举报
回复
新手求解,这个read()为什么这么慢呢?
techie 2017-09-20
  • 打赏
  • 举报
回复
这是我显示慢的程序,我用了一个新的线程来读取数据,线程里面是一个死循环,但显示无法直接显示到richTextBox,所以用了Invoke方法。可是我发送数据的速度只有15KB/s,电脑却显示不及,拔掉网线30秒后数据才更新完,链接时间越长,未显示数据越多。今天我看了异步的Socket,写了一个如5楼的程序,现在不清楚如何一直读取数据并显示。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net.Sockets;
using System.Threading;

namespace TCP_Socket_Test
{
    public partial class Form1 : Form
    {

        public TcpClient client;
        private int TcpClientOpenClose = 0;
        delegate void SetTextCallback(string text);
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }
        private void label1_Click(object sender, EventArgs e)
        {
        }
        private void button1_Click(object sender, EventArgs e)
        {
            if (TcpClientOpenClose == 0)
            {
                string ip = textBox1.Text;
                string port = textBox2.Text;
                int i;
                if (port.Length != 0)
                {
                    i = Convert.ToInt32(port);
                }
                else
                {
                    i = 0;
                }
                label3.ForeColor = Color.Gray;
                TcpTest(i, ip);
                TcpClientOpenClose = 1;
                button1.Text = "断开连接";
            }
            else if (TcpClientOpenClose == 1)
            {
                TopClientClose(client);
                button1.Text = "连接";
            }
        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {

        }
        //Port Number Cheak
        private void NumberKeyPress(object sender, KeyPressEventArgs e)
        {
            if (!(Char.IsNumber(e.KeyChar)) && e.KeyChar != (char)8)
            {
                e.Handled = true;
            }
            else
            {
                //MessageBox.Show("请输入数字!");
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            System.Environment.Exit(0);
        }
        private int TcpTest(int TcpPortNum, string TcpHostName)
        {
            try
            {
                client = new TcpClient(TcpHostName, TcpPortNum);
                Thread ThreadClient = new Thread(new ThreadStart(TcpClientRead));
                ThreadClient.Start();
                label3.ForeColor = Color.Lime;
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
                label3.ForeColor = Color.Red;
                TopClientClose(client);
            }

            return 0;
        }

        // This method demonstrates a pattern for making thread-safe
        // calls on a Windows Forms control. 
        //
        // If the calling thread is different from the thread that
        // created the TextBox control, this method creates a
        // SetTextCallback and calls itself asynchronously using the
        // Invoke method.
        //
        // If the calling thread is the same as the thread that created
        // the TextBox control, the Text property is set directly. 

        private void SetText(string text)
        {
            // InvokeRequired required compares the thread ID of the
            // calling thread to the thread ID of the creating thread.
            // If these threads are different, it returns true.
            if (this.richTextBox1.InvokeRequired)
            {
                SetTextCallback d = new SetTextCallback(SetText);
                this.Invoke(d, new object[] { text });
            }
            else
            {
                this.richTextBox1.Text = text;
            }
        }
        private void TcpClientRead()
        {
            NetworkStream ns = client.GetStream();
            byte[] bytes = new byte[1024];
            string TextDisplay;
            for (; ; )
            {
                int bytesRead = ns.Read(bytes, 0, bytes.Length);
                TextDisplay = Encoding.Default.GetString(bytes);

                this.SetText(TextDisplay);
                Console.WriteLine(Encoding.ASCII.GetString(bytes, 0, bytesRead));
            }
        }

        private void TopClientClose(TcpClient client)
        {
            //this.Dispose();
            client.Close();
            label3.ForeColor = Color.Gray;
        }
        private void richTextBox1_TextChanged(object sender, EventArgs e)
        {
            richTextBox1.SelectionStart = richTextBox1.Text.Length;
            richTextBox1.ScrollToCaret();
        }
    }
}
techie 2017-09-20
  • 打赏
  • 举报
回复
这是我的程序:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Net;
using System.Net.Sockets;


namespace Socket_Test
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
// State object for receiving data from remote device.
public class StateObject {
    // Client socket.
    public Socket workSocket = null;
    // Size of receive buffer.
    public const int BufferSize = 256;
    // Receive buffer.
    public byte[] buffer = new byte[BufferSize];
    // Received data string.
    public StringBuilder sb = new StringBuilder();
}


    // The port number for the remote device.
    private const int port = 5000;

    // ManualResetEvent instances signal completion.
    private static ManualResetEvent connectDone =
        new ManualResetEvent(false);
    private static ManualResetEvent sendDone =
        new ManualResetEvent(false);
    private static ManualResetEvent receiveDone =
        new ManualResetEvent(false);

    // The response from the remote device.
    private static String response = String.Empty;

    public static  void StartClient()
    {
        // Connect to a remote device.
        try
        {
            // Establish the remote endpoint for the socket.
            // The name of the 
            // remote device is "host.contoso.com".
            IPHostEntry ipHostInfo = Dns.GetHostEntry("192.168.1.195");
            IPAddress ipAddress = ipHostInfo.AddressList[0];
            IPEndPoint remoteEP = new IPEndPoint(ipAddress, port);

            // Create a TCP/IP socket.
            Socket client = new Socket(AddressFamily.InterNetwork,
                SocketType.Stream, ProtocolType.Tcp);

            // Connect to the remote endpoint.
            client.BeginConnect(remoteEP,
                new AsyncCallback(ConnectCallback), client);
            connectDone.WaitOne();

            // Send test data to the remote device.
            Send(client, "This is a test<EOF>");
            sendDone.WaitOne();

            // Receive the response from the remote device.
            Receive(client);
            receiveDone.WaitOne();

            // Write the response to the console.
            Console.WriteLine("Response received : {0}", response);

            // Release the socket.
            client.Shutdown(SocketShutdown.Both);
            client.Close();

        }
        catch (Exception e)
        {
            Console.WriteLine(e.ToString());
        }
    }

    private static void ConnectCallback(IAsyncResult ar)
    {
        try
        {
            // Retrieve the socket from the state object.
            Socket client = (Socket)ar.AsyncState;

            // Complete the connection.
            client.EndConnect(ar);

            Console.WriteLine("Socket connected to {0}",
                client.RemoteEndPoint.ToString());

            // Signal that the connection has been made.
            connectDone.Set();
        }
        catch (Exception e)
        {
            Console.WriteLine(e.ToString());
        }
    }

    private static void Receive(Socket client)
    {
        try
        {
            // Create the state object.
            StateObject state = new StateObject();
            state.workSocket = client;

            // Begin receiving the data from the remote device.
            client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                new AsyncCallback(ReceiveCallback), state);
        }
        catch (Exception e)
        {
            Console.WriteLine(e.ToString());
        }
    }

    private static void ReceiveCallback(IAsyncResult ar)
    {
        try
        {
            // Retrieve the state object and the client socket 
            // from the asynchronous state object.
            StateObject state = (StateObject)ar.AsyncState;
            Socket client = state.workSocket;

            // Read data from the remote device.
            int bytesRead = client.EndReceive(ar);

            if (bytesRead > 0)
            {
                // There might be more data, so store the data received so far.
                state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead));

                // Get the rest of the data.
                client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                    new AsyncCallback(ReceiveCallback), state);
            }
            else
            {
                // All the data has arrived; put it in response.
                if (state.sb.Length > 1)
                {
                    response = state.sb.ToString();
                }
                // Signal that all bytes have been received.
                receiveDone.Set();
            }
        }
        catch (Exception e)
        {
            Console.WriteLine(e.ToString());
        }
    }

    private static void Send(Socket client, String data)
    {
        // Convert the string data to byte data using ASCII encoding.
        byte[] byteData = Encoding.ASCII.GetBytes(data);

        // Begin sending the data to the remote device.
        client.BeginSend(byteData, 0, byteData.Length, 0,
            new AsyncCallback(SendCallback), client);
    }

    private static void SendCallback(IAsyncResult ar)
    {
        try
        {
            // Retrieve the socket from the state object.
            Socket client = (Socket)ar.AsyncState;

            // Complete sending the data to the remote device.
            int bytesSent = client.EndSend(ar);
            Console.WriteLine("Sent {0} bytes to server.", bytesSent);

            // Signal that all bytes have been sent.
            sendDone.Set();
        }
        catch (Exception e)
        {
            Console.WriteLine(e.ToString());
        }
    }

        private void button1_Click(object sender, EventArgs e)
        {
            //Socket
            StartClient();
            
        }
        
    }
}
xian_wwq 2017-09-18
  • 打赏
  • 举报
回复
lz最好贴下代码 要测试绝对的socket传输效率 不要把接收和解析混在一起 很多时候系统瓶颈在数据解析而不是数据收发
无情时尚 2017-09-17
  • 打赏
  • 举报
回复
TCP读是很快的,我猜,你是不是读完显示在界面上用了+=来赋值,在你关掉下位机设备后,显示却还在进行,不知道猜得对不???
  • 打赏
  • 举报
回复
把你的应用程序缓冲区设置为500K字节,然后只“接收”之后什么也不做,看看自己写的代码到底是什么操作比较慢。
xuzuning 2017-09-17
  • 打赏
  • 举报
回复
发送端关了,就不再会发送数据了。但还能不断更新20秒才能更新完,显然是你的更新代码有问题

111,092

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧