c# - 监视套接字是否有新数据然后处理该数据的最佳方法是什么?

标签 c# multithreading .net-3.5 sockets sunspot

请原谅我的 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 应用程序调用相应的发送方法两次,其中包含以下数据:

{ '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,因此这些文件会破坏您的消息检测。通常的处理方法是为您的协议(protocol)创建一个 header 规范,并检测您是否需要一个 header (在这种情况下,查找\0 将表示消息的结束)或者您是否正在等待一定数量的 header 。数据(可以由最后收到的 header 指定。)如果这没有意义,并且您认为可能需要使用此技术,请告诉我,我将添加到此答案中。

关于c# - 监视套接字是否有新数据然后处理该数据的最佳方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/453609/

相关文章:

c# - 从 MemoryStream c# 解压缩 JPEG

Java多线程HttpClient-4.3.3问题

c++ - 为什么 C++17 中没有 std::future::then?

c# - 将工具提示添加到组框

visual-studio-2010 - <RequiredTargetFramework> 和 <targetframeworkversion> 之间有什么区别?

c# - 将 Oracle 序列 Nextval 返回到 C# 变量中

c# - 以编程方式检查 MSI 的产品版本

Java为每个数据库行创建唯一的线程

c# - IList<T>.Split() 扩展方法的方法签名

c# - MVC C# 编译 debug = true 仍然捆绑