首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >TcpClient BottleNeck

TcpClient BottleNeck
EN

Stack Overflow用户
提问于 2011-08-18 03:20:31
回答 2查看 1.6K关注 0票数 2

我正在尝试创建一个自包含的类,用于维护到服务器的Tcp连接。

我使用了以下类变量:

代码语言:javascript
复制
TcpClient tcpClient;
NetworkStream networkStream;
BinaryReader mReader;
BinaryWriter mWriter;

并使用以下代码对它们进行初始化:

代码语言:javascript
复制
tcpClient = new TcpClient(host, 443);
networkStream = tcpClient.GetStream();
mReader = new BinaryReader(networkStream);
mWriter = new BinaryWriter(networkStream);

receiveMessage = new Thread(new ThreadStart(ReceiveMessages));
receiveMessage.Start();

我正在使用阻塞调用进行读取。来自服务器的每个数据包都带有4个字节(一个整数)作为前缀,它们定义了确切的数据包大小。我使用的是我编写的一个名为ByteBuffer的类,它有一个列表(Byte)来存储传入的字节。该类有一些函数可以根据服务器协议使用ReadInt()、ReadString()等将int和其他类型从字节列表的顶部拉出。

以下是接收器线程:

代码语言:javascript
复制
private void ReceiveMessages()
{
    while (tcpClient.Connected)
    {
        if (tcpClient.Available >= 4)
        {
            try
            {
                ByteBuffer message = new ByteBuffer();
                message.AddBytes(mReader.ReadBytes(4));
                int mSize = message.ReadInt();
                message.AddBytes(mReader.ReadBytes(mSize - 4));
                MessageProcessor.Process(message);
            }
            catch (Exception ex)
            {
               Print(ex.Message);
            }
        }
        Thread.Sleep(1);
    }
    Print("Receiver thread terminated.");
    Reconnect();
}

作为参考,MessageProcessor是一个静态类,它查看数据包信息并适当地响应服务器。

我的问题是,当连接上的流量开始变得非常高时,响应开始明显延迟。我想知道,就tcp连接而言,我是不是做错了什么?我应该尝试编写一个异步版本的类吗?C#列表对象是否太慢而不能如此频繁地使用(在ByteBuffer中)?

这真的是我第一次尝试网络编程,所以任何建议都会非常有帮助。

谢谢。

EN

回答 2

Stack Overflow用户

发布于 2011-08-18 04:19:52

我会像这样重写你的ReceiveMessages方法,这样就去掉了不好的Thread.Sleep。使用速度更快的字节数组。

就像@jgauffin所说的,异步网络代码要好得多,但它更容易搞砸。如果你刚开始学习网络编程,最好保持简单。

我希望这对你更好。

注意消息没有4字节头

代码语言:javascript
复制
private void ReceiveMessages()
    {

        while (tcpClient.Connected) {
            try {

                var networkstream = tcpClient.GetStream();
                var header = new byte[4];
                networkstream.Read(header, 0, 4);

                int len = 0;
                // calculate length from header
                // Do reverse for BigEndian, for little endian remove
                Array.Reverse(header);
                len = BitConverter.ToInt32(header, 0);

                var message = new byte[len];
                networkstream.Read(message, 0, message.Length);

                // Process message

            }
            catch (Exception ex)
            {
                Print(ex.Message);
                // Exit loop something went wrong
                break;
            }
        }

        Print("Receiver thread terminated.");
        Reconnect();

    }
票数 2
EN

Stack Overflow用户

发布于 2011-08-18 03:40:30

切换到异步处理。使用线程和Thread.Sleep是不好的。

看看Socket.BeginReceive,或者在您的案例中是NetworkStream.BeginRead

您还可以使用我的新库:http://blog.gauffin.org/2012/05/griffin-networking-a-somewhat-performant-networking-library-for-net/

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7098248

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档