我创建了一个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();
}
}
}
}