Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.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# 如何解析在memorystream中接收的数据?_C#_Sockets_Tcpclient - Fatal编程技术网

C# 如何解析在memorystream中接收的数据?

C# 如何解析在memorystream中接收的数据?,c#,sockets,tcpclient,C#,Sockets,Tcpclient,我不熟悉使用插座。我有一个非常基本的客户端,它发送请求并等待响应。响应是一个流,但有两个部分。第一部分以ANS作为前缀,是一组键/值对,其形式为:key:value,每对在单独的一行上 响应的第二部分以RCT作为前缀,这是需要直接发送到打印机的预格式化文本 那么,提取响应的两个部分的最佳方法是什么呢?在第一部分中,获取每个Key:Value对。我甚至可能不需要它们全部,但我必须查看每一个,看看它们的值是什么,然后决定如何处理它们 我目前正在将响应写到一个文本框中,只是为了了解它在做什么,但现在我

我不熟悉使用插座。我有一个非常基本的客户端,它发送请求并等待响应。响应是一个流,但有两个部分。第一部分以ANS作为前缀,是一组键/值对,其形式为:key:value,每对在单独的一行上

响应的第二部分以RCT作为前缀,这是需要直接发送到打印机的预格式化文本

那么,提取响应的两个部分的最佳方法是什么呢?在第一部分中,获取每个Key:Value对。我甚至可能不需要它们全部,但我必须查看每一个,看看它们的值是什么,然后决定如何处理它们

我目前正在将响应写到一个文本框中,只是为了了解它在做什么,但现在我需要实际处理数据

以下是接收到的数据样本:

ANS Result: Data Received                                                                
RCPRES:Q[81]
TML:123
OPP:
MRR:000000999999
<several dozen more KEY:Value pairs>
RCTNov 05 2013  04:03 pm      Trans# 123456

           <pre-formatted text>
ANS结果:收到数据
RCPRES:Q[81]
TML:123
目镜肺体积描记图:
MRR:00000099999
RCTNov 05 2013 04:03下午Trans#123456

将溪流想象成一条传送带,传送带上有一个门可以容纳物品。所以当其他人把东西往上加的时候,你会在门后有一个缓冲区。在你的大门后面的某个地方有一个传感器,它向另一个人发出停止把东西放在线路上的信号。你不必知道传感器的位置有多远。 另一个人可能正在快速添加项目(直到传感器提示他暂停),也可能正在缓慢添加项目

您可以通过调用.Peak()检查门后备份的项目数 您还可以通过调用.read()从线路上读取(通过大门)一个或多个框

读取一个字节将是一个方框,读取一个整数将是4个方框;整数的长度为4字节。 或者你可以读出一个(比如)4个整数的数组,即16个盒子/字节

(我想如果你要求读取比缓冲区中更多的数据,那么它要么阻塞(等待队列更靠前的人发送更多的框,要么抛出异常……你需要试试看)

好的,现在来看看你们的数据。你们已经很容易了。每一个键值对都用一个新行分开。 您可以做的是读取一个字节并将其转换为一个字符,然后检查它是否为新行字符,如果没有,则将其添加到缓冲区,以便在最终找到一个字节时转换为字符串

然而,这是混乱和低效的。 您可以做的是创建一个实现TextReader的读卡器,例如,使用内存流

StreamReader实现了一个ReadLine()方法,它将为您实现这一点

现在,在while循环中,从套接字/StreamReader中逐行读取。 然后检查每一行是否为键值对或RCT内容

如果是KVP,请将其添加到列表中,或者在冒号上拆分并添加到字典中;或者类似的内容,以便以后使用

如果是RCT,则调用ReadToEnd()连接两个字符串(RCT到换行符和ReadToEnd),并将其传递到打印机


您还将在开始时考虑ANS。比如说使用重载。

考虑到缓冲区已经完全加载到内存后,您将使用它,您最好希望的是高效的数组操作。据我所知,
MemoryStream
类只不过是一个
内存中字节数组的外观(当然,添加了正确的定位处理)

您最好以最小的有效增量迭代流,因此假设您的示例文本是真实的,并且取决于新行是CR、LF还是CR+LF,它可能是一个或两个字节。迭代直到找到您期望的RCT前缀(假设在流中的其他位置找不到该序列)应该允许您假设您仍在处理KV对,并做出相应的响应

一旦到达RCT前缀,您似乎需要切换到特定于您的实现的固定宽度处理方法


就这个系统的高级设计而言,我可能会推荐一个捕获/状态对象,它能够表示每个不同的可能KV对(假设固定值仍然有相关的隐式键)根据所需的格式,您需要至少两个不同的解析器来处理请求;一个用于KEY:VALUE格式的显式KV对,另一个用于强格式部分的隐式KV对。有了这些解析器,只需迭代流字节并将消息的部分委派给每个解析器即可基于“阶段”感谢你们两位,巴布科克先生和达西先生的清晰解释。我能够把我的大脑围绕在做我需要的事情所必需的逻辑上。我会仔细考虑这两种方法,看看我能想出什么。你一开始是如何掌握你的套接字的?我怀疑你可能正在使用一个网络流,然后你就可以使用它如果是这样的话,你可以绕过内存流直接进入StreamReader。