Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/279.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# TCPClient在向TCPListener发送消息后运行超时_C#_.net Core_Tcplistener - Fatal编程技术网

C# TCPClient在向TCPListener发送消息后运行超时

C# TCPClient在向TCPListener发送消息后运行超时,c#,.net-core,tcplistener,C#,.net Core,Tcplistener,我想创建一个.NET核心TCP服务器来侦听传入的消息。我创建了一个小类用于测试: internal class TCPServer { private readonly TcpListener tcpListener; public TCPServer() { tcpListener = new TcpListener(IPAddress.Parse("127.0.0.1"), 1234); } public asy

我想创建一个.NET核心TCP服务器来侦听传入的消息。我创建了一个小类用于测试:

internal class TCPServer
{
    private readonly TcpListener tcpListener;

    public TCPServer()
    {
        tcpListener = new TcpListener(IPAddress.Parse("127.0.0.1"), 1234);
    }

    public async Task Start()
    {
        tcpListener.Start();

        while (true)
        {
            TcpClient tcpClient = await tcpListener.AcceptTcpClientAsync();
            NetworkStream networkStream = tcpClient.GetStream();
            byte[] messageBuffer = new byte[tcpClient.ReceiveBufferSize];
            int bytesRead = networkStream.Read(messageBuffer, 0, tcpClient.ReceiveBufferSize);
            string dataReceived = Encoding.ASCII.GetString(messageBuffer, 0, bytesRead);

            Console.WriteLine("Message from tcp client: " + dataReceived);
        }
    }
}
向该侦听器发送消息时,客户端本身会超时。正如你在这里看到的

我试图通过添加这一行来解决它

tcpClient.Close();
但是我得到了这个错误


如何向该服务器发送消息而不出错?

如何启动测试服务器?您是否检查了1234端口是否已打开?我建议通过“telnet 127.0.0.1 1234”进行检查

如果是,你能分享客户的代码吗

如果没有,您能否共享启动服务器的代码? 我试着通过上面的代码运行它,它作为客户机使用telnet工具运行得非常好

class Program
{
    static void Main(string[] args)
    {
        TCPServer server = new TCPServer();
        Console.WriteLine("Starting...");
        server.Start();
        Console.WriteLine("Done.");
        Console.WriteLine("Press any key to quit.");
        Console.ReadKey();
    }
}

internal class TCPServer
{
    private readonly TcpListener tcpListener;

    public TCPServer()
    {
        tcpListener = new TcpListener(IPAddress.Parse("127.0.0.1"), 1234);
    }

    public async Task Start()
    {
        tcpListener.Start();
        try
        {
            while (true)
            {
                TcpClient     tcpClient     = await tcpListener.AcceptTcpClientAsync();
                NetworkStream networkStream = tcpClient.GetStream();
                byte[]        messageBuffer = new byte[tcpClient.ReceiveBufferSize];
                int           bytesRead     = networkStream.Read(messageBuffer, 0, tcpClient.ReceiveBufferSize);
                string        dataReceived  = Encoding.ASCII.GetString(messageBuffer, 0, bytesRead);
                Console.WriteLine("Message from tcp client: " + dataReceived);
            }
        }
        finally
        {
            tcpListener.Stop();
        }
    }
}

问题是您在循环中处理了客户机套接字。一旦建立了客户机套接字,就需要保持该套接字的活动状态

这不是正确的“服务器”代码,但它将向您展示我的意思并解决您的问题:

while (true)
{
    var tcpClient = await tcpListener.AcceptTcpClientAsync();

    while(true){
        var messageBuffer = new byte[4096];
        
        Console.WriteLine("Waiting for data...");
        int bytesRead;
        
        try
        {
            bytesRead = tcpClient.GetStream().Read(messageBuffer, 0, messageBuffer.Length);
        }catch{ break; } // disconnected
        
        var dataReceived = Encoding.ASCII.GetString(messageBuffer, 0, bytesRead);
        Console.WriteLine($"Message from tcp client ({bytesRead} bytes): {dataReceived}");
    }
}
此解决方案可以实现这一点,但不能同时将多个客户端连接到服务器。为了做到这一点,您需要使用TPL,或者在最坏的情况下,为每个客户机创建一个线程


请看一下/
EndRead
以了解我的意思。

TCP是健壮的,因为每条消息都会收到一个ACK,并且当没有收到ACK时,消息会根据设置自动重新发送3到5次。超时表示未收到ACK。30秒后超时,可能每5秒重试5次,30秒后连接关闭。看起来客户端发送了消息,然后在服务器收到消息之前关闭。客户端不应该关闭。所以您认为代码很好,客户端工具不应该关闭客户端?我认为如果客户端在发送数据后立即关闭,可能会出现争用情况。服务器可能无法获取所有数据,然后由于TCP重试而导致超时。这不会解决问题,您只是将问题转移到了
任务中
我只是想强调一下,这可能是Olaf启动服务器的方式有问题。例如,wait server.Start();异步静态void Main内部的调用导致代码出现问题。