gpt4 book ai didi

c# - 客户端关闭时 NetworkStream 在 Read() 上抛出异常

转载 作者:太空宇宙 更新时间:2023-11-03 16:19:13 27 4
gpt4 key购买 nike

我创建的应用程序遇到了一些问题。一般情况(以下描述与问题无关的1-1): 我有一个WCF客户端-服务器应用程序,用于在多个站点收集数据。客户端检索本地数据(一些文件等),将其发送到数据中心的服务器,该服务器处理它。客户端从本地主机获取大部分数据,但其中一些数据是从 LAN 上的不同服务器检索的。这是我的问题开始的地方。我必须创建第三个应用程序,将数据发送到指定的客户端。在这篇文章的提醒中,我将客户端和服务器称为同一 LAN 上的应用程序(因此不是上面数据中心中的服务器)

我尝试使用命名管道,它在同一台主机上进行了出色的进程间交互,但服务器到服务器的速度非常慢。 (如果有人想知道为什么会这样,请不要犹豫告诉我。一些测试发送和接收仅几个字节就达到了 1000 毫秒)

所以我开始使用 TcpClient 类。测试显示响应速度比 NP 等价物快得多,所以我决定使用这个选项。

现在,当客户端和服务器都按预期启动和结束时,一切都很好。问题出现在服务器启动、客户端已连接、服务器正在等待其 stream.Read() 方法,然后客户端应用程序退出时:

Unable to read data from the transport connection: De externe host heeft een verbinding verbroken.(第二部分翻译:现有连接被远程主机强行关闭。)

此刻我用 Try-Catch 语句包装了整个部分,在 IoException 上重新启动了整个过程。这确实有效,但当我读到几篇关于“异常应该是异常的东西!”的帖子时,感觉不太好。

最后的问题是:如何避免这种异常?(在现实生活中保持服务器和客户端应用程序之间连接的正常方法是什么?)

服务器 TcpListener serverSocket = new TcpListener(System.Net.IPAddress.Any, 8888); TcpClient clientSocket = default(TcpClient);

        while (true)
{
serverSocket.Start();
clientSocket = serverSocket.AcceptTcpClient();

while ((true))
{
try
{
NetworkStream networkStream = clientSocket.GetStream();
byte[] bytesFrom = new byte[10025];
networkStream.Read(bytesFrom, 0, (int)clientSocket.ReceiveBufferSize);//THIS THROWS THE EXCEPTION WHEN A CLIENT QUITS
string dataFromClient = System.Text.Encoding.ASCII.GetString(bytesFrom);
dataFromClient = dataFromClient.Substring(0, dataFromClient.IndexOf("$"));
Console.WriteLine(" >> Data from client - " + dataFromClient);
string serverResponse = "Server response " + DateTime.Now.ToString("HH:mm:ss,fff");
Byte[] sendBytes = Encoding.ASCII.GetBytes(serverResponse);

int len = sendBytes.Length;
networkStream.WriteByte((byte)(len / 256));
networkStream.WriteByte((byte)(len & 255));

networkStream.Write(sendBytes, 0, sendBytes.Length);
networkStream.Flush();
}
catch (System.IO.IOException ex)
{
Console.WriteLine(ex.ToString());
break;
}

}
clientSocket.Close();
serverSocket.Stop();
}
}

客户

System.Net.Sockets.TcpClient clientSocket = new System.Net.Sockets.TcpClient();


private void button2_Click(object sender, EventArgs e)
{
NetworkStream serverStream = clientSocket.GetStream();
byte[] outStream = System.Text.Encoding.ASCII.GetBytes("Message from Client$");
serverStream.Write(outStream, 0, outStream.Length);
serverStream.Flush();
int len = serverStream.ReadByte() * 256;
len += serverStream.ReadByte();

byte[] inStream = new byte[len];
serverStream.Read(inStream, 0, len);
string returndata = System.Text.Encoding.ASCII.GetString(inStream);
msg("Data from Server : " + returndata);
}

private void button1_Click_1(object sender, EventArgs e)
{
clientSocket.Connect("127.0.0.1", 8888);
}

最佳答案

我对 Socket API 的理解是,您应该在完成发送后调用 Shutdown(Write)。然后,读取直到流返回 0。这意味着另一端也调用了 Shutdown

只有在您关闭写入(使用Shutdown)并接收到零长度读取后,通信才真正在线上完成。现在 Dispose Socket 因为它现在已经不存在了。

那样的话,只有在出现网络错误或错误时才会出现异常。在那种情况下,您可能应该放弃当前的“事务”并重新启动它。

关于c# - 客户端关闭时 NetworkStream 在 Read() 上抛出异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14552496/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com