select的列子说明select内部实现原理

1:select内部是个数组,而epoll内部结构是红黑二叉树
2:select查询起来慢,而epoll查询起来快
3:每次循环,内部都要发生拷贝(查看相关代码)而epoll不需要这样的操作,也就是初始化一次拷贝
#include
#include<winsock2.h>
#include<windows.h>
#include
#include
int main()
{
std::vectorclients;
WSAData data;
if (WSAStartup(MAKEWORD(2, 2), &data) == SOCKET_ERROR) {
std::cout << (“WSAStartUp Error”) << std::endl;
}
SOCKET socket_fd = socket(AF_INET, SOCK_STREAM, 0);
sockaddr_in add_ress;
add_ress.sin_family = AF_INET;
add_ress.sin_port = htons(8080); //绑定端口号
add_ress.sin_addr.S_un.S_addr = htonl(INADDR_ANY); //能够接受任意ip地址消息
bind(socket_fd, (sockaddr*)&add_ress, sizeof(add_ress));
listen(socket_fd, 5);在这里插入代码片
fd_set read_fd;
fd_set temp_fd;
FD_ZERO(&read_fd);
FD_ZERO(&temp_fd);
FD_SET(socket_fd, &read_fd);
TIMEVAL tv;//设置超时等待时间
tv.tv_sec = 1;
tv.tv_usec = 0;
std::size_t max_fd = socket_fd;
while (1) {
temp_fd = read_fd;
//因为底层内部实现会删除temp_fd的集合,因此要加一个局部数据
int ret = select(max_fd + 1, &temp_fd, NULL, NULL, &tv); //最后一个参数表上阻塞
if (ret == -1) {
break;
}
//如果socket_fd在temp_fd集合内,说有事件来了
if (FD_ISSET(socket_fd, &temp_fd)) {
sockaddr_in add_client;
int len = sizeof(add_client);
SOCKET client_fd = accept(socket_fd, (SOCKADDR*)&add_client, &len);
clients.emplace_back(client_fd);
FD_SET(client_fd, &read_fd);
auto fd = std::find_if(clients.begin(), clients.end(), [max_fd](SOCKET fd)->bool {return fd > max_fd;});
if (fd != clients.end()) {
max_fd = *fd; //更新fd
}
}
else {
//其实从这地方也能看出,select的底层结构是数组,
int count = clients.size();
for (int i = 0;i < count;++i) {
if (FD_ISSET(clients[i], &temp_fd)) {
char buffer[100] = { 0 };
int bytes = recv(clients[i], buffer, 100, 0);
if (bytes == -1) {
continue;
}
if (bytes == 0) {//客户端退出了
SOCKET temp_fd = clients[i];
closesocket(temp_fd);
clients.erase(clients.begin()+i);
FD_CLR(temp_fd, &read_fd);
//read_fd.fd_array[i] = 0; //傻逼底层,竟然不删除,垃圾
auto fd = std::find_if(clients.begin(), clients.end(), [max_fd](SOCKET fd)->bool {return fd > max_fd;});
if (fd == clients.end()) {
max_fd = socket_fd;
}
else {
max_fd = *fd; //更新fd
}
continue;
}
else {
//处理消息, 不写了
}
}
}
}
}
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

尹平华

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值