请原谅我的C#.Net新手状态.如果这很明显并且我从文档中错过了它,那么将会感谢指向相关页面或示例代码的链接.
我正在开发一个应用程序,它将接受来自Java应用程序的TCP套接字连接.(是的,那部分需要Java.它是Sun SPOT设备,Java是唯一的选择.)Java应用程序将定期将新数据写入套接字,而我的应用程序的工作是接收byte [],转换它是一个字符串,处理数据(更新UI等),并可能将数据转发到另一台运行类似C#.NET应用程序的计算机上.
这就是我到目前为止所做的:现在,应用程序在启动时旋转了一个打开套接字的线程.Java应用程序可以成功连接到套接字,以便正常工作.我一直在寻找在的NetworkStream的beginRead
方法和dataAvailable
,length
和CanRead
性质,但我不能完全肯定,当我读了一个数据包,通常约为512字节,但可以改变如何确定.
如果Java应用程序将数据写入流或存在积压的数据(Java应用程序将相当快速地传递数据.)如何确保我一次只读取一个数据包?如果Java应用程序null在写入时终止数据,那会有帮助吗?够了吗?
最后,套接字只接收一个连接,但我需要保持打开,直到出现错误或连接终止.处理这方面最优雅的方法是什么?我不认为关闭并重新打开每个数据包将起作用,因为在Sun SPOT基站上运行的Java应用程序的快速火灾(几乎实时)方面.现在,当基站终止时,我的应用程序死了一个响亮而痛苦的死亡.:)
感谢您阅读并提供任何帮助.
"如果Java应用程序将数据写入流中,或者存在积压的数据(Java应用程序将快速传递数据.)我如何确保一次只读取一个数据包?"
注意不要假设您可以控制哪些数据在哪个数据包中结束.如果您尝试发送字节数据{ 'H', 'e', 'l', 'l', 'o' }
,则无法保证所有这些数据都将在单个数据包中发送.尽管极不可能仍然可能每个数据包只能包含一个字节,因此您将在5个不同的事件中接收所有五个字节.关键是,不要以这种方式依赖数据包.相反,定义您自己的End Of Message终结符,并简单地将所有传入数据抛入某种字节缓冲区,并检测是否存在任何这些终结符.如果是这样,请阅读该终结器.例如,您可以从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将表示消息的结尾)或者如果您正在等待一定数量的数据(可以由收到的最后一个标题指定.)如果这没有意义,你认为你可能需要使用这种技术让我知道,我将添加到这个答案.