我试图Socket.Select
在多线程应用程序中使用,我不想使用async socket
,所以这是我的代码:-
public class Server {
private TcpListener m_listener;
private IConnectionFactory m_factory;
private List<Socket> Sockets = new List<Socket>();
private ConcurrentDictionary<Socket, Connection> Clients = new ConcurrentDictionary<Socket, Connection>();
private ConcurrentDictionary<string, ConcurrentQueue<Socket>> Threads = new ConcurrentDictionary<string, ConcurrentQueue<Socket>>();
private int maxsockets = 0;
private object sync = new object();
public Server(string ip, int port, IConnectionFactory factory, int maxsockets) {
IPAddress ipa = IPAddress.Parse(ip);
TcpListener listener = new TcpListener(ipa, port);
this.maxsockets = maxsockets;
m_listener = listener;
m_factory = factory;
int threads = maxsockets <= 100 ? 1 : maxsockets / 100;
for (int i = 0; i < threads; i++) {
Thread th = new Thread(HandelSockets);
th.Name = i.ToString();
Threads.TryAdd(i.ToString(), new ConcurrentQueue<Socket>());
th.Start();
}
}
public void HandelSockets() {
ConcurrentQueue<Socket> queue = Threads[Thread.CurrentThread.Name];
Connection temp;
Socket sock;
while (true) {
try {
lock (sync) {
while (queue.TryDequeue(out sock)) {
if (Clients.TryGetValue(sock, out temp)) {
if (!temp.Alive) {
Sockets.Remove(sock);
Clients.TryRemove(sock, out temp);
} else {
temp.Receive();
Console.WriteLine("recved from thread num : " + Thread.CurrentThread.Name);
}
}
}
}
} catch { }
Thread.Sleep(1);
}
}
public void Run() {
m_listener.Start();
Console.WriteLine("listen started");
Sockets.Add(m_listener.Server);
while (true) {
try {
var temp_list = Sockets.ToList();
Socket.Select(temp_list, null, null, 1000);
foreach (Socket socket in temp_list) {
if (socket == m_listener.Server) {
var sock = m_listener.AcceptSocket();
Sockets.Add(sock);
Connection conn = m_factory.Create(sock);
Clients.TryAdd(sock, conn);
} else if (Clients.Count >= maxsockets) {
Clients[socket].OnMaxConnections();
break;
} else {
if (!Threads.Values.Any(x => x.Contains(socket))) {
var quque = Threads.Values.Where(x => !x.Contains(socket)).OrderBy(x => x.Count).First();
lock (sync) {
quque.Enqueue(socket);
}
}
break;
}
}
} catch {
}
}
}
}
问题是一段时间后,其中一个连接的套接字将被延迟,其中一个套接字将停止发送或接收,直到其他套接字之一这样做!或者它可能需要几秒/分钟才能恢复接收和发送!
我不知道为什么会发生这种情况!?也许我选择队列的方式?,我希望有人能指出我可能导致延迟发生的原因,谢谢。