Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/google-chrome/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 什么';监视套接字以获取新数据,然后处理该数据的最佳方法是什么?_C#_Multithreading_.net 3.5_Sockets_Sunspot - Fatal编程技术网

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

C# 什么';监视套接字以获取新数据,然后处理该数据的最佳方法是什么?,c#,multithreading,.net-3.5,sockets,sunspot,C#,Multithreading,.net 3.5,Sockets,Sunspot,请原谅我的C#Net新手身份。如果这是显而易见的,而我在文档中没有看到,请提供相关页面或示例代码的链接 我正在开发一个应用程序,它将接受来自Java应用程序的TCP套接字连接。(是的,这部分需要Java。它是Sun SPOT设备,Java是唯一的选项。)Java应用程序将定期向套接字写入新数据,我的应用程序的任务是接收字节[],将其转换为字符串,处理数据(更新UI等),并可能将数据转发到运行类似C#.NET应用程序的另一台计算机上 到目前为止,我所做的是:现在,应用程序在启动时启动一个线程,打开

请原谅我的C#Net新手身份。如果这是显而易见的,而我在文档中没有看到,请提供相关页面或示例代码的链接

我正在开发一个应用程序,它将接受来自Java应用程序的TCP套接字连接。(是的,这部分需要Java。它是Sun SPOT设备,Java是唯一的选项。)Java应用程序将定期向套接字写入新数据,我的应用程序的任务是接收字节[],将其转换为字符串,处理数据(更新UI等),并可能将数据转发到运行类似C#.NET应用程序的另一台计算机上

到目前为止,我所做的是:现在,应用程序在启动时启动一个线程,打开一个套接字。Java应用程序可以成功连接到套接字,以便正常工作。我正在查看NetworkStream的
beginRead
方法和
dataAvailable
length
CanRead
属性,但我不完全确定如何确定何时读取了一个数据包,通常约512字节,但可能会有所不同


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

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


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

当您阅读流式数据时,您需要一些前哨/终止字符或已知大小的数据来确定何时停止阅读和处理信息。空字符或换行符是常见的。另一种技术是使用一个固定大小的标题来指定主体的长度

套接字将保持打开状态,直到您关闭它或另一端终止,在这种情况下,您将在从套接字读取数据时收到错误,您需要重新处理它。NetworkStream在读或写操作期间从远程关闭套接字时引发IOException。

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

小心不要假设您可以控制哪些数据最终进入哪个数据包。如果您试图发送字节数据
{'H','e','l','l','o'}
则无法保证所有这些数据都将在单个数据包中发送。虽然极不可能,但仍有可能每个数据包只包含一个字节,因此您将在5个不同的事件中接收所有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将表示消息的结束),或者是否正在等待一定数量的数据(可以由接收到的最后一个头指定)如果这不合理,并且您认为您可能需要使用此技术,请告诉我,我将补充此答案。

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

TCP。谢谢,我会修改这篇文章。你需要通过检查每个字节来处理一些事情。如果使用header方法,则可以为header读取固定数量的字节。从中读取车身尺寸,然后使用车身的固定尺寸再次调用Read。那么你就不需要检查所有的字节了。我关于读取上面固定大小的评论适用于阻塞读取。这非常有用。我所知道的是,即将输入的数据不会跨行,因此\n或\0字符将用作终端字符。这基本上是传感器数据读数,从一个点传递到基座,然后再传递到我的C#app。IEEE地址,传感器信息。我认为这应该是公认的答案,尽管你做了一些不同的事情。@jxpx-你需要进一步的clari吗