我会用TcpListener创建一个tcp服务器,但是我不知道什么是最好的解决方案。 我尝试了3个例子。见下文。
示例1 (我使用了BeginAcceptTcpClient)
class Program
{
static void Main(string[] args)
{
var endPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 4567);
var listener = new TcpListener(endPoint);
listener.Start();
AcceptTcpClient(listener);
while (true)
{
}
}
public static void AcceptTcpClient(TcpListener listener)
{
listener.BeginAcceptTcpClient(ClientConnected, listener);
}
public static void ClientConnected(IAsyncResult asyncResult)
{
var listener = (TcpListener)asyncResult.AsyncState;
var client = listener.EndAcceptTcpClient(asyncResult);
AcceptTcpClient(listener);
DoAsync(client);
}
}
示例2 (我将BeginAcceptTcpClient与AutoResetEvent一起使用)
class Program1
{
private static readonly AutoResetEvent CONNECTION_WAIT_HANDLE = new AutoResetEvent(false);
static void Main(string[] args)
{
var endPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 4567);
var listener = new TcpListener(endPoint);
listener.Start();
while (true)
{
listener.BeginAcceptTcpClient(ClientConnectedHandle, listener);
CONNECTION_WAIT_HANDLE.WaitOne();
CONNECTION_WAIT_HANDLE.Reset();
}
}
public static void ClientConnectedHandle(IAsyncResult asyncResult)
{
var listener = (TcpListener)asyncResult.AsyncState;
var client = listener.EndAcceptTcpClient(asyncResult);
CONNECTION_WAIT_HANDLE.Set();
DoAsync(client);
}
}
示例3 (我使用了AcceptTcpClientAsync)
class Program2
{
static async Task Main(string[] args)
{
var endPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 4567);
var listener = new TcpListener(endPoint);
listener.Start();
while (true)
{
var client = await listener.AcceptTcpClientAsync();
DoAsync(client);
}
}
public static void AcceptTcpClient(TcpListener listener)
{
listener.BeginAcceptTcpClient(ClientConnected, listener);
}
public static void ClientConnected(IAsyncResult asyncResult)
{
var listener = (TcpListener)asyncResult.AsyncState;
var client = listener.EndAcceptTcpClient(asyncResult);
AcceptTcpClient(listener);
DoAsync(client);
}
}
我认为最好的解决方案是最后一个(示例3),但我不确定。您如何看待?
答案 0 :(得分:0)
示例3 使用基于任务的异步模式(TAP),这是docs中所述的建议用于新开发的异步设计模式。
TAP使用一种方法来表示异步操作的启动和完成。这与异步编程模型(APM或IAsyncResult)模式和基于事件的异步模式(EAP)形成对比。 APM需要Begin和End方法。 EAP需要一种具有Async后缀的方法,并且还需要一个或多个事件,事件处理程序委托类型和EventArg派生的类型。 TAP中的异步方法在操作名称之后的Async后缀中返回了等待类型的方法,例如Task,Task,ValueTask和ValueTask。
答案 1 :(得分:-1)
这是我在项目中使用的代码。它是仅接收异步服务器,但您可以根据自己的需要在Task.Run()
中对其进行修改。我已注释掉代码,以便您了解其工作原理。
static async Task Main(string[] args)
{
await RunServer();
}
static async Task RunServer()
{
TcpListener Listener = new TcpListener(IPAddress.Any, YOURPORTHERE); // Set your listener
Listener.Start(); // Start your listener
while (true) // Permanent loop, it may not be the best solution
{
TcpClient Client = await Listener.AcceptTcpClientAsync(); // Waiting for a connection
_ = Task.Run(() => { // Connection opened. Do operations in a new thread, meanwhile the server is ready to accept other connections in parallel
try
{
var Stream = Client.GetStream(); // (read-only) get data bytes
if (Stream.CanRead) // Verify if the stream can be read.
{
byte[] Buffer = new byte[Client.ReceiveBufferSize]; // Initialize a new empty byte array with the data length.
StringBuilder SB = new StringBuilder();
do // Start converting bytes to string
{
int BytesReaded = Stream.Read(Buffer, 0, Buffer.Length);
SB.AppendFormat("{0}", Encoding.ASCII.GetString(Buffer, 0, BytesReaded));
} while (Stream.DataAvailable); // Until stream data is available
if (SB != null) // Stream data is ready and converted to string
// Do some stuffs
}
}
catch (Exception Ex) // In case of errors catch it to avoid the app crash
{
ConsoleMessage.Error(Ex.ToString()); // Detailed exception
}
});
}
}