2016-10-03 51 views
0

我写了一个VB.Net应用程序,它连接到一个远程IP /端口组合,输出稳定的消息流。 IP地址可以是本地主机,也可以是远程机器。在套接字上接收数据的最有效的方法

远程进程可以在任何时候停止和启动,我的进程需要连接到它并简单地开始接收。两者之间没有谈判使用哪个端口。

我现在的代码使用TcpClient和NetworkStream一次读取一个字节。它被转换为相应的ASCII字符(所有的信息都是ASCII文本),并被附加到一个字符串中,直到收到一个EOL字符。一旦该行被添加到要处理的队列中,字符串将被截断并且该过程再次开始。在这种情况下,一次听一个字节可能不是最有效的方法。

我现在正在测试应用程序,并遇到一些严重的性能问题。虽然我当前的代码有效,但它无法处理抛出的数据量。虽然它每秒可以处理500条消息,但实际上它在每秒1500次的速度下挣扎,并在20%的CPU处达到峰值。

我确定瓶颈是每次读取一个字节的数据 - 有没有办法加快速度?理想情况下,我希望一次读入一行数据,直到收到EOL字符,但这种能力似乎不存在于TcpClient中。

套接字编程不是我的强项,所以也许我错过了一些明显的东西。帮帮我 !

+0

我会说通过TCP进行通信的最佳方式是实现[** message framing **](http://stackoverflow.com/a/37352525/3740093),但如果您希望它适合您当前模型,你也可以使用[**'StreamReader' **](https://msdn.microsoft.com/en-us/library/system.io.streamreader(v = vs.110).aspx)。 - 请记住,通过实施消息框架,您将同时实施一种识别不同种类数据(例如文本,图像,文件等)的方法。 –

+0

这些消息是可变长度的,所以我看不到消息帧如何工作 - 它们只是纯文本,没有花哨的编码。除非我错了(我可能是)不是StreamReader绑定到本地文件而不是套接字? –

+0

'StreamReader'是**流_reader _ **。它具有从其他流中读取文本的功能。要引用文档,StreamReader _“以特定编码从字节流中读取字符”。_请参阅[**其构造函数之一**](https://msdn.microsoft.com/zh-cn/library/ yhfzs7at(v = vs.110)的.aspx)。 - “这些消息是可变长度的,所以我不能看到消息框架如何工作 - 它们只是纯文本,没有花哨的编码。” - 我不明白。 “变长”是什么意思?另外,如果他们不使用任何编码,你怎么发送它们? –

回答

-2

尝试使用System.Text命名空间中的ASCIIEncoding.GetString方法。它应该将一个字节数组转换为一个字符串,而不是一次一个字节。

Dim ascii As New ASCIIEncoding() 
'*** define bytes() byte array here *** 
Dim decoded As String = ascii.GetString(bytes) 

此方法还有一个unicode变体。

+0

这会如何帮助他?如果他一次只得到一个字节,他就回到他开始的地方。如果他一次获取多个字节,他可能在缓冲区中有两个消息位。 –

0

Bytewise IO通常在教程中显示,因为它非常容易。它不适合生产。

当编程套接字使用最高级别的抽象,你可以。理想情况下,您放弃原始套接字并通过诸如HTTP或websockets之类的内容请求数据。可用的库。

如果你坚持使用原始套接字,你可以尝试一个基于行的格式,使用StreamReader/Writer。不需要ASCII,只需使用UTF8这是默认值。

读者可以通过类似的方式获得:new StreamReader(new NetworkStream(socket))

相关问题