.NET中的TCP / IP套接字连接
时间:2020-03-06 15:05:30 来源:igfitidea点击:
对于我当前的项目,我需要通过tcp / ip套接字连接请求XML数据。为此,我使用了TcpClient类:
Dim client As New TcpClient() client.Connect(server, port) Dim stream As NetworkStream = client.GetStream() stream.Write(request) stream.Read(buffer, 0, buffer.length) // Output buffer and return results...
现在,此方法适用于小反应。但是,当我开始接收更大的数据块时,数据似乎突然以套接字方式推送到套接字连接上。发生这种情况时,stream.Read调用仅读取第一个突发,因此我错过了其余的响应。
解决此问题的最佳方法是什么?最初我尝试循环直到拥有有效的XML文档,但是我发现在流之间.Read调用有时会关闭基础流,而我会错过数据的最后一部分。
解决方案
我们创建一个读取循环。
Stream.Read返回到目前为止已读取的字节的int值,如果到达流的末尾,则返回0。
因此,它像:
int bytes_read = 0; while (bytes_read < buffer.Length) bytes_read += stream.Read(buffer, bytes_read, buffer.length - bytes_read);
编辑:现在,问题是如何确定缓冲区的大小。如果服务器先发送了大小,那没关系,我们可以使用上面的代码段。但是,如果必须阅读直到服务器关闭连接,则必须使用try / catch(即使知道大小,也还是个好主意),然后使用bytes_read来确定接收到的内容。
int bytes_read = 0;
try
{
int i = 0;
while ( 0 < (i = stream.Read(buffer, bytes_read, buffer.Length - bytes_read) )
bytes_read += i;
}
catch (Exception e)
{
//recover
}
finally
{
if (stream != null)
stream.Close();
}
读取不能保证完全读取流。它返回读取的实际字节数,如果没有更多的字节要读取,则返回0。我们应该继续循环以从流中读取所有数据。
这是实现"响应"响应字符串的一种可能方法。如果需要字节数组,只需保存ms.ToArray()。
string response;
TcpClient client = new TcpClient();
client.Connect(server, port);
using (NetworkStream ns = c.GetStream())
using (MemoryStream ms = new MemoryStream())
{
ns.Write(request);
byte[] buffer = new byte[512];
int bytes = 0;
while(ns.DataAvailable)
{
bytes = ns.Read(buffer,0, buffer.Length);
ms.Write(buffer, 0, bytes);
}
response = Encoding.ASCII.GetString(ms.ToArray());
}
我强烈建议我们尝试使用WCF执行此类任务。经过不那么陡峭的学习过程,它为我们提供了比原始套接字通信更多的好处。
对于前面的任务,我同意前面的答案,我们应该使用循环并根据需要动态分配内存。

