我正在建立一个简单的TCP客户端和服务器作为我的网络项目的基础。我计划将async await技术用于未来的证明和可扩展的服务器。
如果我输入错误的IP地址,客户端无法连接到我的服务器并抛出异常。我可以使用try / catch捕获异常,但这是推荐的方法吗?
你们对实施有什么看法?有什么评论让我改进吗?
我的服务器
private void startServer_Click(object sender, RoutedEventArgs e)
{
if (anyIP.IsChecked == true)
{
listener = new TcpListener(IPAddress.Any, Int32.Parse(serverPort.Text));
Logger.Info("Ip Address : " + IPAddress.Any + " Port : " + serverPort.Text);
}
else
{
listener = new TcpListener(IPAddress.Parse(serverIP.Text), Int32.Parse(serverPort.Text));
Logger.Info("Ip Address : " + serverIP.Text + " Port : " + serverPort.Text);
}
try
{
listener.Start();
Logger.Info("Listening");
HandleConnectionAsync(listener, cts.Token);
}
//finally
//{
//cts.Cancel();
//listener.Stop();
//Logger.Info("Stop listening");
//}
//cts.Cancel();
}
async Task HandleConnectionAsync(TcpListener listener, CancellationToken ct)
{
while (!ct.IsCancellationRequested)
{
Logger.Info("Accepting client");
//TcpClient client = await listener.AcceptTcpClientAsync();
TcpClient client = await listener.AcceptTcpClientAsync();
Logger.Info("Client accepted");
EchoAsync(client, ct);
}
}
async Task EchoAsync(TcpClient client, CancellationToken ct)
{
var buf = new byte[4096];
var stream = client.GetStream();
while (!ct.IsCancellationRequested)
{
var amountRead = await stream.ReadAsync(buf, 0, buf.Length, ct);
Logger.Info("Receive " + stream.ToString());
if (amountRead == 0) break; //end of stream.
await stream.WriteAsync(buf, 0, amountRead, ct);
Logger.Info("Echo to client");
}
}
private void stopServer_Click(object sender, RoutedEventArgs e)
{
cts.Cancel();
listener.Stop();
Logger.Info("Stop listening");
}
我的客户
private void connect_Click(object sender, System.Windows.RoutedEventArgs e)
{
IPAddress ipAddress;
int port;
//TODO Check if ip address is valid
ipAddress = IPAddress.Parse(serverIP.Text);
//TODO port range is 0-65000
port = int.Parse(serverPort.Text);
StartClient(ipAddress, port);
}
private static async void StartClient(IPAddress serverIpAddress, int port)
{
var client = new TcpClient();
//can i try/catch to catch await exception?
try
{
await client.ConnectAsync(serverIpAddress, port);
}
catch (Exception e)
{
Logger.Info(e);
}
Logger.Info("Connected to server");
using (var networkStream = client.GetStream())
using (var writer = new StreamWriter(networkStream))
using (var reader = new StreamReader(networkStream))
{
writer.AutoFlush = true;
for (int i = 0; i < 10; i++)
{
Logger.Info("Writing to server");
await writer.WriteLineAsync(DateTime.Now.ToLongDateString());
Logger.Info("Reading from server");
var dataFromServer = await reader.ReadLineAsync();
if (!string.IsNullOrEmpty(dataFromServer))
{
Logger.Info(dataFromServer);
}
}
}
if (client != null)
{
client.Close();
Logger.Info("Connection closed");
}
}
答案 0 :(得分:3)
我有一个.NET TCP/IP FAQ,我建议你去了解一些基础知识。
在简要介绍一下你的代码后,这些要点对我来说很突出:
ReadLineAsync
会让您受到轻微的DoS攻击,因为您无法指定该行的最大允许大小。ReadAsync
和WriteAsync
可能会抛出。不太明显的是任何套接字方法都可能抛出,包括AcceptTcpClientAsync
。async Task
方法,因此异常只会默默地结束该方法。 StartClient
方法更有问题,因为它是async void
。您需要考虑应用程序对错误检测和重试策略的需求,并在每个级别应用适当的处理。总之,我重申了我的评论:我强烈建议只是自托管SignalR。如果您别无选择,套接字应仅 。