我正在用D编写服务器应用程序,该应用程序应该能够同时管理n个连接。
为了实现这一点,我正在使用std.socket.Socket.select。这很好。但是我无法将会话特定的数据绑定到套接字,并且我看不到任何方法来执行此操作,因为套接字不允许保存用户特定数据的句柄。之后
Socket.select(socketSet, null, null);
我能够获得所有受影响的套接字,但是无法将此套接字分配给我的用户特定的会话数据。我怎么了这样可以达到我的目标吗?还是应该根据自己的需求选择其他方式?
我的相关代码:
ushort port = 5010;
stoprequest = false;
auto listener = new TcpSocket();
assert(listener.isAlive);
listener.blocking = false;
listener.bind(new InternetAddress(port));
listener.listen(10);
enum MAX_CONNECTIONS = 100;
auto socketSet = new SocketSet(MAX_CONNECTIONS + 1);
Socket[] reads;
Session[] sessions;
while (true)
{
socketSet.add(listener);
foreach (session; sessions)
socketSet.add(session.socket);
Socket.select(socketSet, null, null);
for (size_t i = 0; i < reads.length; i++)
{
if (socketSet.isSet(reads[i]))
{
// Now i should acces to session related data, but how?
char[1024] buf;
auto datLength = reads[i].receive(buf[]);
if (datLength == Socket.ERROR)
writeln("Connection error.");
else if (datLength != 0)
{
writefln("Received %d bytes from %s: \"%s\"", datLength, reads[i].remoteAddress().toString(), buf[0..datLength]);
continue;
}
else { // Error Handling. Shortened, since unimportant for the example}
reads[i].close();
reads = reads.remove(i);
i--;
}
}
if (socketSet.isSet(listener))
{
Socket sn = null;
sn = listener.accept();
if (reads.length < MAX_CONNECTIONS)
{
Session session = new Session();
session.socket = sn;
sessions ~= session;
}
else { // Error Handling for too many connection. Shortened, since unimportant for the example}}
}
socketSet.reset();
}
使用poll()
的提示很有帮助。读完https://daniel.haxx.se/docs/poll-vs-select.html之后,我认为这两种变体都可以工作,而且它们都不是真实的东西。为了有效,我应该更好地处理libev
。幸运的是,在这个特定项目中,效率不是我的问题。由于这个原因,我将使用select()
,因为我发现访问handle
给了我一个唯一的数字,该数字可以传递给自己的查找表。这使我可以将会话数据分配给套接字。因此,我宁愿坚持使用std.socket.Socket
的封装功能,而不要解决它。
因此,我的具体问题可以用:]回答。
使用Socket.handle标识套接字并管理与会话相关的 数据
您可以考虑的其他一些选择: