如何为 TCP 消息响应设置正确的缓冲区大小
How to set a correct buffer size for TCP message responses
这就是我目前向外部 TCP 服务器发送数据的方式
byte[] data = new byte[0] /* the data to send */;
TcpClient client = new TcpClient("127.0.0.1", 3000); // connect to the tcp server
NetworkStream stream = client.GetStream();
await stream.WriteAsync(data, 0, data.Length);
data = new byte[256]; // set the buffer size
int responseBytes = await stream.ReadAsync(data, 0, data.Length); // store the response to the buffer
string responseData = System.Text.Encoding.ASCII.GetString(data, 0, responseBytes);
stream.Close();
client.Close();
对于响应,我必须在此处设置缓冲区大小 new byte[256]
。但是,如果响应大于此大小怎么办?我无法确定正确的大小,因为我只是连接到他的外部服务器,向它发送消息并期待响应。有什么方法可以让它变得动态吗?
作为旁注:我正在向诊所服务器发送各种 HL7 消息,他们将发回 HL7 ACK 消息作为响应。这提供了有关 HL7 ACK 消息的一些信息
https://healthstandards.com/blog/2007/02/01/ack-message-original-mode-acknowledgement/
示例 ACK 可以是
MSH|^~&|CATH|StJohn|AcmeHIS|StJohn|20061019172719||ACK^O01|MSGID12349876|P|2.3
MSA|AA|MSGID12349876
For the response I have to setup the buffer size here new byte[256]. But what if the response is greater than this size?
然后你调用 stream.ReadAsync()
并将你的缓冲区(或解码后的字符串)附加到一个更大的缓冲区,直到你知道你已经收到了整个消息,无论如何你都需要这样做:来自一个的 Write()套接字的一端不需要对应另一端的一个 Read()。多次写入可以在一次读取中读取,反之亦然。
所以像这样:
data = new byte[256]; // set the buffer size
var builder = new StringBuilder();
do
{
int responseBytes = await stream.ReadAsync(data, 0, data.Length); // store the response to the buffer
string responseData = System.Text.Encoding.ASCII.GetString(data, 0, responseBytes);
builder.Append(responseData);
} while (responseBytes > 0)
请注意,这恰好适用于 ASCII,因为它没有多字节字符。如果它是 UTF-8 或类似的编码,第 256 个字节可能是继续到下一次读取的字符的开始,即下一次读取的字节 1(也许是 2)。
此代码还假定您希望继续阅读直到连接关闭(然后 responseBytes = 0
)。如果此协议有长度前缀或消息终止符,您必须处理这些。
通常您不想自己实现这个 low-level 东西,难道没有处理 HL7 协议的可用库吗?
这就是我目前向外部 TCP 服务器发送数据的方式
byte[] data = new byte[0] /* the data to send */;
TcpClient client = new TcpClient("127.0.0.1", 3000); // connect to the tcp server
NetworkStream stream = client.GetStream();
await stream.WriteAsync(data, 0, data.Length);
data = new byte[256]; // set the buffer size
int responseBytes = await stream.ReadAsync(data, 0, data.Length); // store the response to the buffer
string responseData = System.Text.Encoding.ASCII.GetString(data, 0, responseBytes);
stream.Close();
client.Close();
对于响应,我必须在此处设置缓冲区大小 new byte[256]
。但是,如果响应大于此大小怎么办?我无法确定正确的大小,因为我只是连接到他的外部服务器,向它发送消息并期待响应。有什么方法可以让它变得动态吗?
作为旁注:我正在向诊所服务器发送各种 HL7 消息,他们将发回 HL7 ACK 消息作为响应。这提供了有关 HL7 ACK 消息的一些信息
https://healthstandards.com/blog/2007/02/01/ack-message-original-mode-acknowledgement/
示例 ACK 可以是
MSH|^~&|CATH|StJohn|AcmeHIS|StJohn|20061019172719||ACK^O01|MSGID12349876|P|2.3 MSA|AA|MSGID12349876
For the response I have to setup the buffer size here new byte[256]. But what if the response is greater than this size?
然后你调用 stream.ReadAsync()
并将你的缓冲区(或解码后的字符串)附加到一个更大的缓冲区,直到你知道你已经收到了整个消息,无论如何你都需要这样做:来自一个的 Write()套接字的一端不需要对应另一端的一个 Read()。多次写入可以在一次读取中读取,反之亦然。
所以像这样:
data = new byte[256]; // set the buffer size
var builder = new StringBuilder();
do
{
int responseBytes = await stream.ReadAsync(data, 0, data.Length); // store the response to the buffer
string responseData = System.Text.Encoding.ASCII.GetString(data, 0, responseBytes);
builder.Append(responseData);
} while (responseBytes > 0)
请注意,这恰好适用于 ASCII,因为它没有多字节字符。如果它是 UTF-8 或类似的编码,第 256 个字节可能是继续到下一次读取的字符的开始,即下一次读取的字节 1(也许是 2)。
此代码还假定您希望继续阅读直到连接关闭(然后 responseBytes = 0
)。如果此协议有长度前缀或消息终止符,您必须处理这些。
通常您不想自己实现这个 low-level 东西,难道没有处理 HL7 协议的可用库吗?