Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

Poll-- the reuse of IO

2025-01-16 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Network Security >

Share

Shulou(Shulou.com)06/01 Report--

one。 About poll

For the IO reuse model, its advantage is undoubtedly that it eliminates the waiting for one IO event to be ready, and instead detects multiple IO data at the same time. When at least one of the waiting events is ready, it will return and tell the user process, "there is data ready, let's see which one is ready to deal with it." for the implementation of IO reuse, in addition to using the select function. Another function that still supports this reuse IO model is the poll function.

two。 The usage of poll function

Although it is also testing and waiting for multiple IO events, poll and select are somewhat different:

In the function parameters

Let's start with nfds, which refers to the number of file descriptors that currently need to be concerned about.

Timeout also sets the timeout, except that unlike select's timeout, which is a structure, it's just an integer type, and it means milliseconds.

Fds is a structure pointer, as follows:

In the structure

Fd represents the file descriptor you care about

Events represents the event that the file descriptor cares about, which is an input parameter that tells the operating system what the action event is concerned about by the event corresponding to the file descriptor, such as read or write.

Revents is an output parameter that tells the user what action event is ready when poll returns. For example, if POLLIN is ready, the value of revent when returned is POLLIN, which tells the user that the POLLIN of the fd event is ready.

Values for events and revents can be as follows:

It should be explained here that there are more than these three options, but these three options are the most commonly used in the discussion here.

Setting events to POLLIN means that fd needs to read the data, while if revents returns POLLIN, it means that data can be read by ready.

Similarly, events is set to POLLOUT to indicate the writing of data that fd is concerned about, while the return of POLLOUT by revents indicates that the write event is ready for data writing

As for POLLPRI, the later explanation is set as an emergency option. In the TCP protocol message, there is an emergency pointer of URG indicating that it should be read from the place where the emergency data is first read. This is also what it means here.

three。 Chestnut time

Similarly, poll can be used to write data communication between server and client based on the TCP protocol, and like select, avoid using multi-process and multi-threading instead of waiting for multiple IO interfaces:

Server server side:

# include # define _ BACKLOG_ 5max / maximum number of waits in the connection request queue in the network # define _ NUM_ 10//IO event structure array size void usage (const char * argv) / / error judgment of command line arguments {printf ("% s [ip] [port]\ n", argv); exit (0) } static int CreateListenSocket (int ip, int port) / / create listening socket {int sock = socket (AF_INET, SOCK_STREAM, 0); if (sock

< 0) { perror("socket"); exit(1); } struct sockaddr_in server;//设置本地网络地址信息 server.sin_family = AF_INET; server.sin_port = htons(port); server.sin_addr.s_addr = ip; if(bind(sock, (struct sockaddr*)&server, sizeof(server)) < 0)//绑定 { perror("bind"); exit(2); } if(listen(sock, _BACKLOG_) < 0)//监听 { perror("listen"); exit(3); } return sock;}int main(int argc, char *argv[]){ if(argc != 3) usage(argv[0]); int port = atoi(argv[2]); int ip = inet_addr(argv[1]); int listen_sock = CreateListenSocket(ip, port);//获取监听socket struct sockaddr_in client;//用于存放client端的网络地址信息 socklen_t client_len = sizeof(client); struct pollfd fds[_NUM_];//用一个结构体数组来存放各种IO事件 fds[0].fd = listen_sock;//将监听套接字放入数组中 fds[0].events = POLLIN;//将监听事件需要的event设置为读取数据POLLIN fds[0].revents = 0; size_t i = 1; for(; i < _NUM_; ++i)//初始化结构体数组中成员 { fds[i].fd = -1; fds[i].events = 0; fds[i].revents = 0; } int max_fd = 1;//设置最大的文件描述符个数 int timeout = 5000;//设置超时时间 while(1) { switch(poll(fds, max_fd, timeout)) { case -1://出错 perror("poll"); break; case 0://超时 printf("timeout...\n"); break; default://至少有一个事件已经就绪,可以进行IO数据的操作 { size_t i = 0; for(; i < _NUM_; ++i) { //判断是否为监听事件就绪,如果是代表有连接请求需要处理 if((fds[i].fd == listen_sock) && (fds[i].revents == POLLIN)) { //处理连接 int accept_sock = accept(listen_sock, (struct sockaddr*)&client, &client_len); if(accept_sock < 0) { perror("accept"); continue; } printf("connect with a client... [ip]:%s [port]:%d\n", inet_ntoa(client.sin_addr), ntohs(client.sin_port)); size_t i = 0; //将创建出新的数据传输socket文件描述符设置进poll结构体数组 for(; i < _NUM_; ++i) { if(fds[i].fd == -1) { fds[i].fd = accept_sock; fds[i].events = POLLIN;//将事件设置为需要读取数据 max_fd++;//更新最大文件描述符个数 break; } } if(i == _NUM_) close(accept_sock);//若超出数组个数则表明当前无法处理,关闭掉 }//表示为其他除了listen socket之外的要进行数据传输的socket else if((fds[i].fd >

0) & (FDS [I] .revents = = POLLIN) {char buf [1024]; / / read data ssize_t size = read (FDS [I] .fd, buf, sizeof (buf)-1) If (size < 0) / / error reading perror ("read") Else if (size = = 0) / / client closes, emptying {printf ("client closed...\ n") in the structure array. / / swap the last valid file descriptor in the structure array with the file descriptor to be closed / / ensure that the currently valid file descriptors are contiguous in the array Struct pollfd tmp = fds [I] Fds [I] = FDS [max _ fd-1]; FDS [max _ fd-1] = tmp / / the one to be deleted after the exchange is at the end of the array Close and set the corresponding position in the array to an invalid value close (FDS [max _ fd-1] .fd) FDS [max _ fd-1] .fd =-1; FDS [max _ fd-1] .events = 0 FDS [max _ fd-1]. Revents = 0;-- max_fd / / update the number of currently valid file descriptors} else// read successfully, output data {buf [size] ='\ 0mm; printf ("client#% s\ n", buf) }} else {} break;}} return 0;}

The client client will not be written here, which is similar to client in socket programming based on TCP protocol.

Run the program:

What needs to be explained here is:

Unlike select, select uses a fd_set data type to store IO file descriptors that require operations. Here poll uses a structure to store file descriptors and event types of concern to locks. Therefore, poll does not handle the upper limit of file descriptors, but it is the same that every poll return still needs to traverse the location where the event is ready to process accordingly. It also has the extra overhead of replication and system traversal, and it is still inefficient when dealing with more events.

Before each loop to select, you need to call the FD_ZERO function to re-initialize the fd_set collection of the corresponding events, because it is not necessary to create and close file descriptors, initialize and then reset the events into the corresponding fd_set one by one. But poll does not need, because using a structure array to manage is equivalent to combining the two steps of setting array in select to store file descriptor and adding settings. Every time poll is performed, the revents corresponding to the event that is ready will be set. When the processing is finished, it will be automatically classified as 0 by the system, and there is no need for manual initialization.

Before the structure array is used, like the newly defined variables, the structure members fd, events and revents are random values, although they will be assigned corresponding valid values when used later, but in order to avoid ambiguity in judgment, it is best to initialize them to unified identifiable invalid values before recycling.

"finish"

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Network Security

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report