繁体   English   中英

监视套接字以获取新数据然后处理该数据的最佳方法是什么?

[英]What's the best way to monitor a socket for new data and then process that data?

请原谅我的C#.Net新手身份。 如果这很明显,但是我从文档中错过了它,则可以访问相关页面或示例代码的链接。

我正在开发一个将接受来自Java应用程序的TCP套接字连接的应用程序。 (是的,在那部分上需要Java。这是Sun SPOT设备,Java是唯一的选择。)Java应用程序将定期将新数据写入套接字,而我的应用程序的工作是获取byte [],进行转换。将其转换为字符串,处理数据(更新UI等),然后将数据转发到另一台运行类似C#.NET应用程序的计算机上。

到目前为止,这是我所做的事情:现在,应用程序在启动时旋转了一个线程,该线程打开了一个套接字。 Java应用程序可以成功连接到套接字,从而可以正常工作。 我一直在查看NetworkStream的beginRead方法以及dataAvailablelengthCanRead属性,但是我不确定如何确定何时读取一个数据包(通常约为512字节),但是可能有所不同。

如果Java应用程序将数据写入流中或存在积压的数据(Java应用程序将相当快地传递数据。)如何确保我一次只读取一个数据包? 如果Java应用程序null在写入时终止了数据,这会有所帮助吗? 够了吗

最后,套接字将仅接收一个连接,但是我需要保持打开状态,直到出现错误或连接终止。 处理这方面最优雅的方法是什么? 我认为关闭和重新打开每个数据包不会起作用,因为在Sun SPOT基站上运行的Java应用程序具有快速启动(几乎实时)的作用。 现在,当基站终止时,我的应用程序死于很大的痛苦。 :)

感谢您的阅读和提供的任何帮助。

“如果Java应用程序将数据写入流,或者存在积压的数据(Java应用程序将相当快地传递数据。)如何确保我一次只读取一个数据包?”

注意不要假设您可以控制哪些数据最终存储在哪个数据包中。 如果尝试发送字节数据{ 'H', 'e', 'l', 'l', 'o' } ,则不能保证所有这些数据都将在单个数据包中发送。 虽然极不可能,但每个数据包可能仅包含一个字节,因此您将在5个不同的事件中接收所有五个字节。 关键是,不要以这种方式依赖数据包。 而是定义您自己的消息结束符,然后将所有传入的数据简单地扔入某种字节缓冲区中,并使用另一个函数来检测是否存在这些终结符。 如果是这样,请阅读该终止符。 举例来说,假设您从Java应用程序调用了两次包含以下数据的各自的send方法:

{ 'H', 'e', 'l', 'l', 'o', '\0' }
{ 'W', 'o', 'r', 'l', 'd', '\0' }

应该如何准备您的应用程序以接收数据应该是这样的:

Server receives { 'H', 'e', 'l' }
Data stored in byte buffer { 'H', 'e', 'l' }
Check byte buffer for message terminator '\0'. None found. Buffer unchanged, no message processed.
Server receives { 'l', 'o', '\0', 'W' }
Data stored in byte buffer { 'H', 'e', 'l', 'l', 'o', '\0', 'W' }
Check byte buffer for message terminator '\0'. 1 found, extracted message { 'H', 'e', 'l', 'l', 'o' } and buffer updated { 'W' }

因此,尽管这并不是您最初提出的问题的完全答案,但我认为它应该为您提供正确的方向。

您可能会遇到的一件事是,根本没有任何字符不能成为数据,而不是消息终止符。 例如,许多文件包含数据\\ 0,因此它们会破坏您的邮件检测。 通常的处理方式是通过为协议创建标头规范并检测您是否期望标头(在这种情况下,寻找\\ 0表示消息的结尾)还是等待一定量的数据(可以通过接收到的最后一个标头来指定。)如果这没有意义,并且您认为您可能需要使用此技术,请告诉我,我将添加到此答案中。

在读取流数据时,您需要一些标记/终止符或已知的数据大小,以确定何时停止读取和处理信息。 空字符或换行符很常见。 另一种技术是使用固定大小的标头,该标头指定主体的长度。

套接字将保持打开状态,直到您将其关闭或另一端终止为止,在这种情况下,从套接字读取该套接字时会遇到错误。 当在读或写操作期间从远程端关闭套接字时,NetworkStream引发IOException。

我们解决这个问题的方法是结合使用前哨字符和固定宽度的字段。 前两个字节是整个数据包的长度标头。 然后,我将数据包读入byte []缓冲区,然后依靠我们自己的数据包结构来了解,例如,前两个字节分别被解释为单独的字段,然后字符串字段以\\ n字符终止(如果您在家得分,则为0x0A)。 然后,通过读取8个连续的字节等来处理长数据字段,这对我们来说似乎很好,但是对于其中一个人控制套接字的两端而不是仅控制套接字两端的情况,这显然是一种解决方案。能够控制一端。 希望这也对其他人有帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM