服务器超时 C#

Server Timeout C#

所以,我正在用 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 防火墙可能阻止了正在使用的端口。出于测试目的,我尝试完全禁用专用网络(例如我所在的网络)的防火墙。不幸的是,这并没有改变任何东西。

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

干杯!

StreamReader.ReadToEnd()NetworkStream 上只会 return 一旦到达流的“结尾”,这在您的示例中不会发生;因此,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,或者是预先发送的长度前缀,告诉客户端还有多少字节要读取。