我想写异步tcp客户端服务器。当我在客户端上调用disconnect方法或在服务器上调用stop方法时,我写了这段代码但有问题。我没有得到异常,我无法确定客户端或服务器不再可用。如何确定客户端或服务器不再可用?
服务器
public class Server
{
private readonly Dictionary<IPEndPoint, TcpClient> clients = new Dictionary<IPEndPoint, TcpClient>();
private readonly List<CancellationTokenSource> cancellationTokens = new List<CancellationTokenSource>();
private TcpListener tcpListener;
private bool isStarted;
public event Action<string> NewMessage;
public async Task Start(int port)
{
this.tcpListener = TcpListener.Create(port);
this.tcpListener.Start();
this.isStarted = true;
while (this.isStarted)
{
var tcpClient = await this.tcpListener.AcceptTcpClientAsync();
var cts = new CancellationTokenSource();
this.cancellationTokens.Add(cts);
await Task.Factory.StartNew(() => this.Process(cts.Token, tcpClient), cts.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default);
}
}
public void Stop()
{
this.isStarted = false;
foreach (var cancellationTokenSource in this.cancellationTokens)
{
cancellationTokenSource.Cancel();
}
foreach (var tcpClient in this.clients.Values)
{
tcpClient.GetStream().Close();
tcpClient.Close();
}
this.clients.Clear();
}
public async Task SendMessage(string message, IPEndPoint endPoint)
{
try
{
var tcpClient = this.clients[endPoint];
await this.Send(tcpClient.GetStream(), Encoding.ASCII.GetBytes(message));
}
catch (Exception exception)
{
}
}
private async Task Process(CancellationToken cancellationToken, TcpClient tcpClient)
{
try
{
var stream = tcpClient.GetStream();
this.clients.Add((IPEndPoint)tcpClient.Client.RemoteEndPoint, tcpClient);
while (!cancellationToken.IsCancellationRequested)
{
var data = await this.Receive(stream);
this.NewMessage.SafeInvoke(Encoding.ASCII.GetString(data));
}
}
catch (Exception exception)
{
}
}
private async Task Send(NetworkStream stream, byte[] buf)
{
await stream.WriteAsync(BitConverter.GetBytes(buf.Length), 0, 4);
await stream.WriteAsync(buf, 0, buf.Length);
}
private async Task<byte[]> Receive(NetworkStream stream)
{
var lengthBytes = new byte[4];
await stream.ReadAsync(lengthBytes, 0, 4);
var length = BitConverter.ToInt32(lengthBytes, 0);
var buf = new byte[length];
await stream.ReadAsync(buf, 0, buf.Length);
return buf;
}
}
客户端
public class Client
{
private TcpClient tcpClient;
private NetworkStream stream;
public event Action<string> NewMessage;
public async void Connect(string host, int port)
{
try
{
this.tcpClient = new TcpClient();
await this.tcpClient.ConnectAsync(host, port);
this.stream = this.tcpClient.GetStream();
this.Process();
}
catch (Exception exception)
{
}
}
public void Disconnect()
{
try
{
this.stream.Close();
this.tcpClient.Close();
}
catch (Exception exception)
{
}
}
public async void SendMessage(string message)
{
try
{
await this.Send(Encoding.ASCII.GetBytes(message));
}
catch (Exception exception)
{
}
}
private async void Process()
{
try
{
while (true)
{
var data = await this.Receive();
this.NewMessage.SafeInvoke(Encoding.ASCII.GetString(data));
}
}
catch (Exception exception)
{
}
}
private async Task Send(byte[] buf)
{
await this.stream.WriteAsync(BitConverter.GetBytes(buf.Length), 0, 4);
await this.stream.WriteAsync(buf, 0, buf.Length);
}
private async Task<byte[]> Receive()
{
var lengthBytes = new byte[4];
await this.stream.ReadAsync(lengthBytes, 0, 4);
var length = BitConverter.ToInt32(lengthBytes, 0);
var buf = new byte[length];
await this.stream.ReadAsync(buf, 0, buf.Length);
return buf;
}
}