TcpClient asyncreceive正在阻塞

时间:2018-03-09 15:13:40

标签: c# .net sockets asynchronous tcpclient

我创建了一个tcp服务器和一个tcp客户端。我试图运行客户端异步但有一些问题。

现在,当我通过await ReceiveAsync(id)调用该函数时,整个程序被阻止。我必须在新任务Task.Run(()=> ReceiveAsync())中启动该函数,然后它才能正常工作。

现在,我想当我使用readlineasync的异步版本时,我可以通过等待ReceiveAsync()调用该函数,一切都可以正常运行。如何实现正确的功能以从服务器接收连续数据,而不会阻止程序并且不创建新任务?

服务器

main.cs

namespace Server
{
    class Program
    {
        static void Main(string[] args)
        {
            // Start the server  
            TcpHelper.StartServer(5678);
            TcpHelper.Listen(); // Start listening.
        }
    }
}

TcpHelper.cs

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;

namespace Server
{
    public class TcpHelper
    {
        private static TcpListener listener { get; set; }
        private static bool accept { get; set; } = false;

        public static void StartServer(int port)
        {
            IPAddress address = IPAddress.Parse("127.0.0.1");
            listener = new TcpListener(address, port);

            listener.Start();
            accept = true;

            Console.WriteLine($"Server started. Listening to TCP clients at 127.0.0.1:{port}");
        }

        public static void Listen()
        {
            if (listener != null && accept)
            {

                // Continue listening.  
                while (true)
                {
                    Console.WriteLine("Waiting for client...");
                    var clientTask = listener.AcceptTcpClientAsync(); // Get the client  

                    if (clientTask.Result != null)
                    {
                        Console.WriteLine("Client connected. Waiting for data.");
                        var client = clientTask.Result;
                        string message = "";

                        while (message != null && !message.StartsWith("quit"))
                        {
                            //for (int i = 0; i < 100; i++)
                            //{
                            //  byte[] data = Encoding.ASCII.GetBytes("Send next data: [enter 'quit' to terminate] ");
                            //  client.GetStream().Write(data, 0, data.Length);
                            //  Thread.Sleep(4000);
                            //}

                            byte[] data = Encoding.ASCII.GetBytes("Send next data: [enter 'quit' to terminate] \n");
                            client.GetStream().Write(data, 0, data.Length);

                            byte[] buffer = new byte[1024];
                            client.GetStream().Read(buffer, 0, buffer.Length);

                            message = Encoding.ASCII.GetString(buffer);
                            Console.WriteLine(message);
                        }

                        Console.WriteLine("Closing connection.");
                        client.GetStream().Dispose();
                    }
                }
            }
        }
    }
}

客户端

using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Threading.Tasks;

namespace TestTcpSocket
{
    class Program
    {
        static void Main(string[] args)
        {

            MainAsync().Wait();
        }

        static async Task MainAsync()
        {
            TcpClient client = Connect(IPAddress.Parse("127.0.0.1"), 5678).Result;
            //await ReceiveAsync(client); // Blocks the whole program
            Task.Run(() => ReceiveAsync(client)); // Works
            string line;
            while ((line = Console.ReadLine()) != null)
            {
                await SendAsync(client, line);
            }
        }

        private static async Task<TcpClient> Connect(IPAddress address, int port)
        {
            TcpClient client = new TcpClient();
            await client.ConnectAsync(address, port);
            return client;
        }

        private static async Task SendAsync(TcpClient client, string message)
        {
            NetworkStream networkStream = client.GetStream();
            StreamWriter writer = new StreamWriter(networkStream);
            StreamReader reader = new StreamReader(networkStream);
            writer.AutoFlush = true;
            await writer.WriteLineAsync(message);
        }

        private static async Task ReceiveAsync(TcpClient client)
        {
            NetworkStream networkStream = client.GetStream();
            StreamWriter writer = new StreamWriter(networkStream);
            StreamReader reader = new StreamReader(networkStream);
            writer.AutoFlush = true;

            while (true)
            {
                string response = await reader.ReadLineAsync();

            }
        }
    }
}

0 个答案:

没有答案