Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/13.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#_Xml_Sockets_Stream - Fatal编程技术网

C# 套接字流不包含整个响应

C# 套接字流不包含整个响应,c#,xml,sockets,stream,C#,Xml,Sockets,Stream,我的c#应用程序中有一些套接字通信。客户端向服务器发送一个请求(一个XML字符串),服务器用另一个XML字符串进行响应 以下是在客户端上运行的代码: using (TcpClient client = new TcpClient(socket.HostName, socket.Port)) { client.SendBufferSize = int.MaxValue; client.ReceiveBufferSize = int.MaxValue; Stream stre

我的c#应用程序中有一些套接字通信。客户端向服务器发送一个请求(一个XML字符串),服务器用另一个XML字符串进行响应

以下是在客户端上运行的代码:

using (TcpClient client = new TcpClient(socket.HostName, socket.Port))
{
    client.SendBufferSize = int.MaxValue;
    client.ReceiveBufferSize = int.MaxValue;
    Stream stream = client.GetStream();

    StreamReader sr = new StreamReader(stream);
    StreamWriter sw = new StreamWriter(stream);
    sw.AutoFlush = true;

    sw.WriteLine(requests.ToXML());

    List<string> xmlStrings = new List<string>();
    while (sr.Peek() > -1)
        xmlStrings.Add(sr.ReadLine());
    string xmlStr = string.Join("\r\n", xmlStrings.ToArray());

    ProcessXMLResponse(xmlStr);

    stream.Close();
    client.Close();
}
使用(TcpClient client=newtcpclient(socket.HostName,socket.Port))
{
client.SendBufferSize=int.MaxValue;
client.ReceiveBufferSize=int.MaxValue;
Stream=client.GetStream();
StreamReader sr=新的StreamReader(流);
StreamWriter sw=新StreamWriter(流);
sw.AutoFlush=true;
sw.WriteLine(requests.ToXML());
List xmlStrings=新列表();
while(sr.Peek()>-1)
Add(sr.ReadLine());
字符串xmlStr=string.Join(“\r\n”,xmlStrings.ToArray());
ProcessXMLResponse(xmlStr);
stream.Close();
client.Close();
}
这在服务器计算机上运行:

using (Stream stream = new NetworkStream(socket))
using (StreamReader sr = new StreamReader(stream))
using (StreamWriter sw = new StreamWriter(stream))
{
    sw.AutoFlush = true;

    List<string> xmlStrings = new List<string>();
        while (sr.Peek() > -1)
    xmlStrings.Add(sr.ReadLine());
    string xmlStr = string.Join("\r\n", xmlStrings.ToArray());
    XmlDocument xml = new XmlDocument();
    xml.LoadXml(xmlStr);

    string responseXML = ProcessXMLRequest(xml);

    sw.WriteLine(response);
    socket.Shutdown(SocketShutdown.Both);
    stream.Close();
}
使用(流=新的网络流(套接字))
使用(StreamReader sr=新StreamReader(stream))
使用(StreamWriter sw=新StreamWriter(流))
{
sw.AutoFlush=true;
List xmlStrings=新列表();
while(sr.Peek()>-1)
Add(sr.ReadLine());
字符串xmlStr=string.Join(“\r\n”,xmlStrings.ToArray());
XmlDocument xml=新的XmlDocument();
LoadXml(xmlStr);
字符串responseXML=ProcessXMLRequest(xml);
sw.WriteLine(响应);
socket.Shutdown(SocketShutdown.Both);
stream.Close();
}
这段代码似乎大部分时间都在工作,但有时(可能是当XML响应很大时?),客户机似乎只收到XML响应的第一部分。sr.Peek()调用返回-1,即使数据尚未全部收到

知道问题出在哪里吗?

如果您尝试使用

sr.ReadToEnd()
而不是

sr.ReadLine()
双方

此外,作为一句忠告,你应该更加努力地有效地处理你的资源:

using (TcpClient client = new TcpClient(socket.HostName, socket.Port))
{
    client.SendBufferSize = int.MaxValue;
    client.ReceiveBufferSize = int.MaxValue;

    Stream stream = client.GetStream();
    //generally, you should avoid calling Dispose() on an object multiple times

    //don't put this in a using block as that implicitly calls Dispose() which internally calls Dispose on the stream as well
    StreamReader sr = new StreamReader(stream);

    //don't put this in a using block as that implicitly calls Dispose() which internally calls Dispose on the stream as well
    StreamWriter sw = new StreamWriter(stream);

    sw.AutoFlush = true;
    sw.WriteLine("test");

    List<string> xmlStrings = new List<string>();
    while (sr.Peek() > -1)
        xmlStrings.Add(sr.ReadLine());
    string xmlStr = string.Join("\r\n", xmlStrings.ToArray());

    //this calls stream.Dispose as well internally
    sr.Close();

    //actually, this also calls stream.Dispose(), but fortunately MS made it safe
    sw.Close();

    ProcessXMLResponse(xmlStr);
}

//At this point all IDisposable objects have been disposed of properly (TcpClient, Stream, StreamReader, StreamWriter)
//we minimized the number of stream.Dispose() calls whereas using 3 using blocks (1 for the stream, 1 for the Reader and 1 for the Writer) would have resulted in 3 calls
使用(TcpClient client=newtcpclient(socket.HostName,socket.Port))
{
client.SendBufferSize=int.MaxValue;
client.ReceiveBufferSize=int.MaxValue;
Stream=client.GetStream();
//通常,应该避免多次对对象调用Dispose()
//不要把它放在using块中,因为它隐式调用Dispose(),而Dispose()也在流上内部调用Dispose
StreamReader sr=新的StreamReader(流);
//不要把它放在using块中,因为它隐式调用Dispose(),而Dispose()也在流上内部调用Dispose
StreamWriter sw=新StreamWriter(流);
sw.AutoFlush=true;
软件写入线(“测试”);
List xmlStrings=新列表();
while(sr.Peek()>-1)
Add(sr.ReadLine());
字符串xmlStr=string.Join(“\r\n”,xmlStrings.ToArray());
//这将在内部调用stream.Dispose
高级关闭();
//实际上,这也调用stream.Dispose(),但幸运的是MS使其安全
sw.Close();
ProcessXMLResponse(xmlStr);
}
//此时,所有IDisposable对象都已正确处置(TcpClient、Stream、StreamReader、StreamWriter)
//我们最小化了stream.Dispose()调用的数量,而使用3个使用块(1个用于流,1个用于读卡器,1个用于写卡器)将导致3个调用
让我们看看:

表示要读取的下一个字符的整数,如果没有要读取的字符或流不支持查找,则为-1

(强调矿山)

网络流

获取一个值,该值指示流是否支持查找。。。此属性始终返回false

基本上,根据文档,您的代码已损坏;我猜当数据随时可用时(这与小负载与大负载的描述一致),它会工作,但当数据不立即可用时,它会失败

基本上,不要在这里使用
Peek
。只需读取数据,直到用完为止。如果要尽量减少代码更改,请执行以下操作:

List<string> xmlStrings = new List<string>();
string line;
while((line = sr.ReadLine()) != null)
    xmlStrings.Add(line);
List xmlStrings=new List();
弦线;
而((line=sr.ReadLine())!=null)
添加(行);

但就我个人而言,我的实现方式会有很大不同。

可能是因为数据尚未完全发送/接收。尝试提前发送长度,并等待socket.Available==length.ReadToEnd对此不受支持,并且它会无限期地阻塞。