【发布时间】:2016-08-25 16:34:50
【问题描述】:
我习惯于开始/结束 APM 模式,我想将我的套接字服务器更新为 .Net 4.5/async/await。我从互联网资源中编写了一个示例代码,但它不起作用。
我希望所有已连接的客户端在被接受连接后都分离到自己的类(尚未实现..)。接受所有传入连接的循环在自己的线程中运行。
基本上 Main.cs 是我接受客户端、为连接创建新类 (Client.cs/Session.cs) 并将接受的客户端指向该类的地方。好吧,这就是我打算做的,它不在代码中,目前的主要问题是我知道如何处理这个接受序列以及为什么我不能同时连接多个客户端?希望你能指出我正确的答案。
提前谢谢你。
代码
Form1.cs
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Server
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
// Own thread for accepting connections
Main ConnectionLoop = new Main(10);
Thread thread = new Thread(new ThreadStart(ConnectionLoop.PrepareThread));
thread.IsBackground = true;
thread.Start();
}
}
}
Main.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace Server
{
public class Main
{
private int m_backLog = 0;
// constructor
public Main(int Backlog)
{
m_backLog = Backlog;
Console.WriteLine("Main class created, backlog: {0}", Backlog);
}
public void PrepareThread()
{
Console.WriteLine("Thread created");
StartAccepting(CancellationToken.None).Wait();
}
private async Task StartAccepting(CancellationToken token)
{
Console.WriteLine("Started listening..");
CancellationTokenSource cts = new CancellationTokenSource();
TcpListener listener = new TcpListener(IPAddress.Any, 6112);
listener.Start();
await AcceptClientsAsync(listener, cts.Token);
// Thread.Sleep(600000);
}
private async Task AcceptClientsAsync(TcpListener listener, CancellationToken token)
{
var clientCounter = 0;
while (!token.IsCancellationRequested)
{
TcpClient client = await listener.AcceptTcpClientAsync().ConfigureAwait(false);
clientCounter++;
Console.WriteLine("Client {0} accepted!", clientCounter);
await EchoAsync(client, clientCounter, token);
}
}
private async Task EchoAsync(TcpClient client, int clientCounter, CancellationToken token)
{
using (client)
{
var buf = new byte[4096]; // buffer for stream
var stream = client.GetStream(); // stream itself
while (!token.IsCancellationRequested)
{
// some conditions we don't know is client connected, lets have timeout
var timeoutTask = Task.Delay(TimeSpan.FromSeconds(15));
var amountReadTask = stream.ReadAsync(buf, 0, buf.Length, token);
var completedTask = await Task.WhenAny(timeoutTask, amountReadTask).ConfigureAwait(false);
if (completedTask == timeoutTask)
{
var msg = Encoding.ASCII.GetBytes("Client timed out");
await stream.WriteAsync(msg, 0, msg.Length);
break;
}
var amountRead = amountReadTask.Result;
if (amountRead == 0) break; // end of stream
await stream.WriteAsync(buf, 0, amountRead, token).ConfigureAwait(false);
}
}
Console.WriteLine("Client {0} disconnected", clientCounter);
}
}
}
【问题讨论】:
标签: c# sockets asynchronous tcp async-await