日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

發布時間:2025/3/11 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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 {
//處理消息, 不寫了
}
}
}
}
}
}

總結

以上是生活随笔為你收集整理的select的列子说明select内部实现原理的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。