[英]C# Concurrent and Async Socket Connections
我正在研究一个简单的套接字服务器,该服务器应该接受多个连接并通过EndAccept()
将EndAccept()
给“连接”类。问题是在接受连接后,代码不接受任何进一步的操作直到连接结束。
我在Main()
创建套接字,然后通过Initialize()
将套接字传递给ServerEnvironment(静态类Initialize()
。
MainSocket.Bind(new IPEndPoint(IPAddress.Parse(Addr), Port));
MainSocket.Listen(10);
ServerEnvironment.Initialize(MainSocket);
while (true)
{
Console.ReadLine();
Console.WriteLine(">>");
}
一旦MainSocket
通过,ServerEnvironment就会从那里接管。
static Socket MainSocket;
public static void Initialize(Socket _MainSocket)
{
MainSocket = _MainSocket;
AcceptGameConnection = new AsyncCallback(AddConnection);
MainSocket.BeginAccept(AcceptGameConnection, null);
}
public static void AddConnection(IAsyncResult Result)
{
Socket UserSocket = MainSocket.EndAccept(Result);
ConnectionCount++;
// Removed the stuff that happens to UserSocket because the same
// symptoms occur regardless of their presence.
MainSocket.BeginAccept(AcceptGameConnection, null);
}
当我搜索这个问题时,我发现多线程可能是我的目的所必需的。 但是,当我使用Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
在Initialize();
和AddConnection();
,出现两个不同的线程ID,所以我假设多线程已经是一种功能,我不需要手动创建一个线程。 但这并不能解释我的问题。
多线程是否需要我能够拥有并发和异步套接字连接?
编辑:绑定错误..绑定到我的局域网地址,这导致一些问题。
如果您使用.net 4.0或更低版本,这就是您希望如何执行此操作
public static void Initialize(Socket _MainSocket)
{
MainSocket = _MainSocket;
AcceptGameConnection = new AsyncCallback(AddConnection);
MainSocket.BeginAccept(result => {
var userSocket = MainSocket.EndAccept(result);
var thread = new Thread(AddConnection);
thread.Start(userSocket);
Initialize(MainSocket);
}, null);
}
public static void AddConnection(IAsyncResult Result)
{
MainSocket.BeginAccept(AcceptGameConnection, null);
}
private static void AddConnection(Socket userSocket)
{
// Removed the stuff that happens to UserSocket because the same
// symptoms occur regardless of their presence.
}
但这就是你在.net 4.5或更高版本中的表现。
public static void Initialize(Socket mainSocket)
{
while(true)
{
var userSocket = await Task.Factory.FromAsync(
mainSocket.BeginAccept,
mainSocket.EndAccept);
ThreadPool.QueueUserWorkItem(_ => AddConnection(userSocket));
}
}
private static void AddConnection(Socket userSocket)
{
// Removed the stuff that happens to UserSocket because the same
// symptoms occur regardless of their presence.
}
问题是,在接受连接之后,代码在连接结束之前不会接受任何进一步的操作。
发生这种情况是因为下一个BeginAccept
调用被某些东西延迟,可能是这里未显示的代码。 异步接受几乎总是毫无意义。 不要盲目地从可怕的微软教程中复制。 你的接受循环应该是:
while (true) {
var socket = Accept();
StartProcessing(socket); //Cannot block!
}
就这样。
您可以使用Task
和await
实现StartProcessing
。 这使得异步套接字IO变得相当简单。 或者,为每个连接启动一个新任务/线程。
简单套接字服务器
这样的事情不存在。 您最好单独留下套接字并使用现成的更高级别协议,例如WCF或HTTP。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.