【问题标题】:Server Timeout C#服务器超时 C#
【发布时间】:2021-12-27 05:05:48
【问题描述】:

所以,我正在用 C# 开发一个客户端应用程序,该应用程序连接到服务器端应用程序(也是用 C# 编写的)。首先,我只是想让应用程序成功地相互通信。目前,我的客户端和服务器都在同一台设备上运行。


服务器端


在服务器端,我使用TcpListener 来接受套接字,打印出它已连接以进行调试、接收请求并发送响应。代码如下:

服务器端代码:

while (true)
{
    // Accept a new connection
    Socket socket = socketListener.AcceptSocket();
    if (socket.Connected)
    {
        Console.WriteLine("\nClient Connected!!\n==================\nClient IP {0}\n", socket.RemoteEndPoint);
        
        // Make a byte array and receive data from the client
        byte[] receive = new byte[1024];
        _ = socket.Receive(receive, receive.Length, 0);
        
        // Convert byte to string
        string buffer = Encoding.ASCII.GetString(receive);

        
        string response = "Test response";
     
        int numBytes = 0;
        try
        {
            if (socket.Connected)
            {
                if ((numBytes = socket.Send(data, data.Length, 0)) == -1)
                    Console.WriteLine("Socket Error: cannot send packet");
                else
                    Console.WriteLine("No. of bytes sent {0}", numBytes);
            }
            else
            {
                Console.WriteLine("Connection Dropped...");
            }
        }
        catch (Exception e)
        {
            Console.WriteLine("An exception has occurred: " + e.ToString());
        }            
    }
}

客户端


在客户端,我使用TcpClient 使用IP 地址(在本例中为127.0.0.1)连接到服务器,建立NetworkStream 对象,发送请求并读取响应.

客户端代码:

private static readonly TcpClient socket = new TcpClient();

private const string IP = "127.0.0.1";
private const int PORT = 46495;

static void Main(string[] args)
{
    try
    {
        socket.Connect(IP, PORT);
    }
    catch (Exception)
    {
        Console.WriteLine("Error connecting to the server.");
        return;
    }

    NetworkStream stream = socket.GetStream();
    stream.ReadTimeout = 2000;

    string request = "Test Request";
    byte[] bytes = Encoding.UTF8.GetBytes(request);
    stream.Write(bytes, 0, bytes.Length);

    StreamReader reader = new StreamReader(stream, Encoding.UTF8);

    try
    {
        string response = reader.ReadToEnd();
        Console.WriteLine(response);
    }
    catch(Exception e)
    {
        Console.WriteLine(e);
    }
}

输出


在服务器端,一切似乎都很好。客户端成功连接到预期的 IP 地址,我收到了预期的请求,并且正确的响应似乎已成功发送。

客户端变得更加复杂。在我期望“测试响应”响应的地方,我得到了一个 SocketException,据我所知,它表明超时???完整的输出可以在下面找到:

System.IO.IOException: Unable to read data from the transport connection: A connection attempt failed because the connected party did not properly respond after a period of time, or an established connection failed because the connected host has failed to respond...
 ---> System.Net.Sockets.SocketException (10060): A connection attempt failed because the connected party did not properly respond after a period of time, or an established connection failed because the connected host has failed to respond.
   at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
   --- End of inner exception stack trace ---
   at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
   at System.IO.StreamReader.ReadBuffer()
   at System.IO.StreamReader.ReadToEnd()
   at Client.Client.Main(String[] args) in C:\Dev\Project Orange Sunshine\Project Orange Sunshine\Client\Client.cs:line 38

我的尝试


首先,我想确保我的服务器实际上首先在发送响应。为了测试这一点,我尝试通过 Web 浏览器访问服务器应用程序。果然,我得到了一个空白页,左上角有预期的“测试响应”文本。对我来说,这表明我的服务器应用程序正在按预期工作。

通过一些谷歌搜索,我找到了类似问题的各种答案,表明 Windows Defender 防火墙可能正在阻止正在使用的端口。出于测试目的,我尝试完全禁用专用网络的防火墙,例如我所在的网络。不幸的是,这并没有改变任何东西。

我觉得我遗漏了一些明显的东西,我们将不胜感激。

干杯!

【问题讨论】:

    标签: c# .net sockets server client


    【解决方案1】:

    NetworkStream 上的StreamReader.ReadToEnd() 只会在到达流的“结束”时返回,这在您的示例中不会发生;因此,StreamReader 超时。

    您应该通过使用较低级别的NetworkStream.Read 方法从流中读取来解决此问题:

    var buffer = new byte[4096];
    var bytesRead = stream.Read(buffer, 0, buffer.Length);
    Console.WriteLine("Read {0} bytes", bytesRead);
    string response = Encoding.UTF8.GetString(buffer, 0, bytesRead);
    Console.WriteLine(response);
    

    为了使这个测试程序更加健壮,您还需要引入“框架”,即服务器向客户端指示它可以停止读取的某种方式。这可以是终止符后缀,例如 HTTP 使用的\r\n,也可以是预先发送的长度前缀,告诉客户端还要读取多少字节。

    【讨论】:

      猜你喜欢
      • 2019-01-20
      • 1970-01-01
      • 1970-01-01
      • 2012-04-15
      • 2011-01-06
      • 1970-01-01
      • 2010-11-12
      • 2012-11-25
      • 2012-12-01
      相关资源
      最近更新 更多