当前位置:网站首页>Select for i/0 multiplexing
Select for i/0 multiplexing
2022-06-22 02:39:00 【Think and act 66】
I/0 Multiplexer select
List of articles
1.select effect
The system provides select Function to implement multiplexing input / Output model :
- select Call is used to let our program monitor the status changes of multiple file descriptors
- The program will stop at select Wait here , Until one or more of the monitored file descriptors have changed state
2.select The function prototype
- int select(int nfds,fd_set* readfds,fd_set* exceptfds,struct timeval* timeout);
- nfds: The value is the value of the maximum file descriptor +1, The function is to control select Polling monitoring range for
- resdfds: Read event collection
- writefds: Write event set
- exceptfds: Exception event collection
- timeout: Block mode delivery NULL, Non blocking delivery 0, With timeout , Used to set select() The waiting time of
3. About fd_set Structure
Is an array of integers , More strictly speaking, it is a “ Bitmap ”, Use the corresponding bit in the bitmap to indicate the file descriptor to monitor :

4. operation fd_set The interface of
- void FD_CLR(int fd, fd_set *set); // take fd From the event collection set Removed from , It's essentially fd The corresponding bit position is 0
- int FD_ISSET(int fd, fd_set *set); // Judge fd Whether the file descriptor is in the collection set among , It's essentially judgment fd Whether the corresponding bit is 0, The return value is 0 Express fd be not in set among , by 1 It means that
- void FD_SET(int fd, fd_set *set); // Set file descriptor to set In the event set , In essence, it's fd The corresponding bit position is 1
- void FD_ZERO(fd_set *set); // Used to empty the event collection , In essence, it's set All bit positions in the are 0
5.select How to use
- select There are three event sets : Read event collection , Write event set , Exception event collection
- When you need to focus on an event of a file descriptor , Add a file descriptor to the corresponding event set
for example : Focus on 0 Read event of file descriptor No , Will 0 No. file descriptor is added to the read event set readfds- If you don't pay attention to certain events , Is to select When passing parameters , Pass on NULL
6.select The return value of
- The return value is the number of ready file descriptors
- The ready file descriptor is stored in the event set and returned to the caller
Be careful :select File descriptors that are not ready will be removed from the event set , Therefore, it is necessary to add again when monitoring again
7.select test
#include <stdio.h>
#include <unistd.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main(){
int listen_sockfd=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(listen_sockfd<0){
perror("socket");
return 0;
}
struct sockaddr_in addr;
addr.sin_familt=AF_INET;
addr.sin_port=htons(29090);
addr.sin_addr.s_addr=inet_addr("0.0.0.0");
int ret=bind(listem_sockfd,(struct sockaddr*)&addr,sizeof(addr));
if(ret<0){
perror("bind");
return 0;
}
listen(listen_sockfd,5);
fd_set readfds;
FD_ZERO(&readfds);
FD_SET(0, &readfds);
FD_SET(listen_sockfd, &readfds);
while(1){
fd_set tmp=readfds;
int ret=select(listen_sockfd+1,&tmp,NULL,NULL,NULL);
printf("ret:%d\n",ret);
if(FD_ISSET(0,&tmp)){
char buf[1024]={
0};
read(0,buf,sizeof(buf)-1);
printf("buf:%s",buf);
}else{
printf("0 is not in readfds\n");
}
if(FD_ISSET(listen_sockfd,&tmp)){
printf("listen_sockfd read\n");
accept(listen_sockfd,NULL,NULL);
}else{
printf("listen_sockfd not in readfds\n");
}
}
return 0;
}
8.select_tcp
The header file my_select.hpp:
#pragma once
#include <stdio.h>
#include <unistd.h>
#include <sys/select.h>
#include <vector>
class SelectSvr{
public:
SelectSvr(){
//1. Empty event collection + initialization max_fd
FD_ZERO(&readfds_);
max_fd_=-1;
}
~SelectSvr(){
}
void AddFd(int fd){
// Add and update the maximum file descriptor
FD_SET(fd,&readfds_);
if(fd>max_fd_){
max_fd_=fd;
}
}
void DeleteFd(int fd){
// Remove the file descriptor and update
FD_CLR(fd,&readfds_);
for(int i=max_fd_;i>==0;i--){
if(FD_ISSET(i,&readfds_)){
max_fd_=i;
break;
}
}
}
int Select(std::vetcor<int>* vec){
int ret=-1;
while(1){
fd_set tmp=readfds_;
ret=select(max_fd_+1,&tmp,NULL,NULL,NULL);
if(ret<0){
return ret;
}else if(ret==0){
continue;
}
for(int i=0;i<max_fd_;i++){
if(FD_ISSET(i,&tmp)){
vec->push_back(i);
}
}
break;
}
return ret;
}
private:
fd_set readfds_;
int msx_fd_;
};
main.cpp:
#include <stdio.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include "my_select.hpp"
/* * 1.tcp Initialization work * 2.select monitor * 3. Handle according to the monitoring * listen_sock * new_sockfd * */
int main(){
int listen_sock = socket(AF_INET, SOCK_STREAM, 0);
if(listen_sock < 0){
perror("socket");
return 0;
}
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(39090);
addr.sin_addr.s_addr = inet_addr("0.0.0.0");
int ret = bind(listen_sock, (struct sockaddr*)&addr, sizeof(addr));
if(ret < 0){
perror("bind");
return 0;
}
listen(listen_sock, 5);
SelectSvr ss;
ss.AddFd(listen_sock);
while(1){
std::vector<int> vec;
int ret = ss.Select(&vec);
if(ret < 0){
continue;
}
for(size_t i = 0; i < vec.size(); i++){
if(listen_sock == vec[i]){
// Listening socket
struct sockaddr_in peer_addr;
socklen_t peer_addr_len = sizeof(peer_addr);
int new_sockfd = accept(listen_sock, (struct sockaddr*)&peer_addr, &peer_addr_len);
if(new_sockfd < 0){
continue;
}
ss.AddFd(new_sockfd);
printf("recv new link, ip : %s, port : %d\n", inet_ntoa(peer_addr.sin_addr), ntohs(peer_addr.sin_port));
}else{
// New connection socket has data coming
char buf[1024] = {
0};
ssize_t recv_size = recv(vec[i], buf, sizeof(buf) - 1, 0);
if(recv_size < 0){
continue;
}else if(recv_size == 0){
ss.DeleteFd(vec[i]);
close(vec[i]);
}else{
printf("[%d sockfd] %s\n", vec[i], buf);
}
}
}
}
return 0;
}
边栏推荐
- When retail digitalization enters a new stage of development, we need to connect the public domain with the private domain
- rt_ Thread thread management
- PMP备考相关敏捷知识
- Automated tools - monitoring file changes
- C ++ Primer 第2章 变量和基本类型 总结
- import和require在浏览器和node环境下的实现差异
- Introduction to excellent verilog/fpga open source project (XXVII) - small CPU
- 华阳智能冲刺深交所:拟募资4亿 复星惟盈是股东
- Li Kou today's question 1108 IP address invalidation
- Chapter 25 digital watermarking technology based on Wavelet Transform
猜你喜欢
随机推荐
Development of power plant compliance test system with LabVIEW
Penetration testing - logic vulnerability topic
postgresql根据时间字段的大小来取数
Array common methods
Using neo4j sandbox to learn neo4j graph data science GDS
Openjudge noi 1.13 46: octal to decimal
Pytorch visualization
Qt程序怎么实现选中ListWidget中的某一行为默认选中
GraphAcademy 课程讲解:《Neo4j 图数据科学简介》
PMP备考相关敏捷知识
基于xposed框架hook使用
Neo4j 技能树正式发布,助你轻松掌握Neo4j图数据库
【1. 快速排序】
Fabric. JS iText set italics manually
Introduction to Apache ActiveMQ Artemis
EMC radiation emission rectification - principle case analysis
What is a neural network
All the knowledge you want to know about the PMP Exam is here
Matlab learning notes (5) import and export of MATLAB data
国产品牌OPPO官方最新出品!这份PPT报告!真刷新我对它认知了







![[proteus simulation] INT0 and INT1 interrupt count](/img/0b/b3f5adb97046d927e501ea34deb3d9.png)

