【问题标题】:"Unable to read data from the transport connection" - C#“无法从传输连接中读取数据” - C#
【发布时间】:2010-09-27 20:11:13
【问题描述】:

我开始涉足网络编程领域,最近我从讲师教程中发现了一个相当古老的示例(或者有人告诉我)。

我们在大学计算机上尝试过,但无法正常工作,因此讲师认为这是由于 Windows 7 或大学计算机系统的安全设置造成的。

渴望找到原因,我决定在家中自己的计算机上运行相同的代码,但毫无疑问它不起作用。

一个解决方案中有两个项目,一个充当客户端,另一个充当服务器。一旦服务器和客户端都相互连接,客户端就会向服务器发送一个简单的字符串,该字符串会打印到控制台。在此之后,适当的连接关闭,应用程序正常退出。

只要服务器确认它已连接到客户端,应用程序就会工作,但它会抛出异常(已捕获并处理)并带有文本:

无法从传输连接读取数据:现有连接被远程主机强行关闭。 - (System.IO.IOException)

现在我刚开始使用 C# 进行网络编程,我不确定该去哪里找,我的讲师说他会在下周的讲座中找出问题的原因和解决方案,但我想采取一些主动并找出自己。

我添加了 Client.cs 和 Server.cs 类以防万一它们有用,调试器认为原因在于 Server.cs 中的第 27 行,即对 streamReader.Readline() 的调用;

注意:这绝不是作业,我只是好奇为什么它不起作用。称之为学习体验 =]

客户端.cs

using System;
using System.Net.Sockets;
using System.IO;

namespace NetworkProgrammingTutorial1Client
{
    class Client
    {
        static void Main(string[] args)
        {
            TcpClient myclient;

            try
            {
                // Create a TcpClient to talk to the local host.
                myclient = new TcpClient("localhost", 1234);
            }
            catch
            {
                Console.WriteLine("Failed to connect to the server.");
                return;
            }

            // get a Network stream from the server
            NetworkStream networkStream = myclient.GetStream();
            StreamWriter streamWriter = new StreamWriter(networkStream);

            streamWriter.WriteLine("Have a message.");
            streamWriter.Flush();
        }
    }
}

Server.cs

using System;
using System.Net.Sockets;
using System.Net;
using System.IO;

namespace NetworkProgrammingTutorial1Server
{
    class Server
    {
        static void Main(string[] args)
        {
            // TcpListener is listening on the given port...                                                 {
            TcpListener tcpListener = new TcpListener(1234);
            tcpListener.Start();     
            Console.WriteLine("Server Started") ;                  
            // Accepts a new connection...
            Socket socketForClient = tcpListener.AcceptSocket();                   
            try
            {
                if (socketForClient.Connected)
                {
                    while (true)
                    {
                        Console.WriteLine("Client connected");
                        NetworkStream networkStream = new NetworkStream(socketForClient);
                        StreamReader streamReader = new StreamReader(networkStream);
                        string line = streamReader.ReadLine();
                        if (line == null)
                            break;
                        Console.WriteLine(line);
                    }
                }

                socketForClient.Close();               
                Console.WriteLine("Exiting...");
            }
            catch(Exception e)
            {
                Console.WriteLine(e.ToString()) ;
            }
        }
    }
}

【问题讨论】:

  • 如果这行得通,我会感到惊讶。每次迭代创建的 NetworkStream 将由 GC 不确定地释放,这将导致底层连接关闭。我将编写一个应该有效的示例。

标签: c# .net networking


【解决方案1】:

试试这个服务器代码:

TcpListener listener = new TcpListener(IPAddress.Any, 1234);
listener.Start();     

using (TcpClient client = listener.AcceptTcpClient())
using (StreamReader reader = new StreamReader(client.GetStream()))
{
    string line;
    while ((line = reader.ReadLine()) != null)
    {
        Console.WriteLine(line);
    }
}

listener.Stop();

这会监听 1234 端口,接受一个客户端,创建一个 StreamReader 并输出客户端发送的所有行,直到客户端关闭连接。然后它停止监听并退出。

如您所见,只创建了一个 StreamReader(不是每一行都重复),并且 TcpClient 和 StreamReader 都在您完成后由 using 语句处理。


您的客户端代码应该可以工作。不过,最好也在这里放置对象:

using (TcpClient client = new TcpClient("localhost", 1234))
using (StreamWriter writer = new StreamWriter(client.GetStream()))
{
    writer.WriteLine("Have a message.");
    writer.Flush();

    writer.WriteLine("Have another message.");
    writer.Flush();
}

【讨论】:

  • 这似乎是一个新手问题,但是为什么使用的是AcceptTcpCLient 而不是AcceptSocket?使用一个比另一个有好处吗?
  • .NET Framework 提供了两种网络编程方式:TcpClient/TcpListener 和 Sockets。 TcpClient/TcpListener 提供了一个高级接口,并且比低级套接字更简单易用。所以新手最好使用TcpClient/TcpListener,避免使用Sockets。
  • Ezxcellent,感谢您的建议。将 Server.cs 更改为您的解决方案后,将发送消息,但之后它会在尝试从客户端读取消息的行抛出 IOException。
  • 我刚刚测试了我的代码,它在我的机器上完美运行。你得到什么 IOException?同一个(连接被远程主机强行关闭)还是另一个?
  • 异常文本为“无法从传输连接读取数据:现有连接被远程主机强制关闭。” - 项目是否以发布模式构建有关系吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-11-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-12
  • 2013-07-04
相关资源
最近更新 更多