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

Multiplexing input / output-select

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

Share

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

1. Select

The system provides select function to realize the multiplexing input / output model. The select system call is used to allow our program to monitor changes in the state of multiple file handles. The program stops at the select to block waiting until one or more of the monitored file handles have a state change.

A file handle is actually an integer. The handles we are most familiar with are 0, 1, 2, 0: standard input, 1: standard output, 2: standard error output. 0, 1, 2 are integers, and the corresponding FILE * structures: stdin, stdout, stderr.

II. Select correlation

1. Select function / / can wait for more than one descriptor at a time

# include

Int select (int nfds, fd_set * readfds, fd_set * writefds

Fd_set * exceptfds, struct timeval * timeout)

(1) parameters:

/ / nfds: the maximum file descriptor value to be monitored + 1

/ / readfds: a collection of readable file descriptors to be detected

/ / wtitefds: a collection of writable file descriptors to be detected

/ / exceptfds: collection of exception file descriptors to be detected

/ / timeout: structure timeval, which is used to set the waiting time of select ()

/ / timeout:

NULL:select () without timeout,select will be blocked until an event occurs on a file descriptor.

0: only detects the status of the descriptor collection and returns immediately without waiting for an external event to occur.

Specific time value: if no event occurs within the specified time period, select will time out to return.

(2) return value:

Successful execution returns the number of file descriptors whose status has changed.

If 0 is returned, it means that the timeout time has elapsed before the state of the descriptor is changed.

When an error occurs,-1 is returned. The cause of the error is stored in errno, and the values of the parameters readfds,writefds,exceptfds and timeout become unpredictable.

(3) the way in which the parameter-value of select is transmitted. At the same time, select file descriptors are qualified.

After the select returns, FD_ISSET polling is required to get the ready descriptor.

Select needs to get the ready socket by traversing the file descriptor after it returns.

2. Other functions

Void FD_CLR (int fd, fd_set * set); / / clear the related fd bits in the descriptive phrase set

Int FD_ISSET (int fd, fd_set * set); / / Test whether the bit of relevant fd in the descriptive phrase set is true

Void FD_SET (int fd, fd_set * set); / / set the bit of the related fd in the descriptive phrase set

Void FD_ZERO (fd_set * set); / / clear the whole part of the descriptive phrase set

# include

Int aio_read (struct aiocb * aiocbp); Link with-lrt.

3. Related structures

Struct timeval {long tv_sec; / * seconds * / long tv_usec; / * microseconds * /}; andstruct timespec {long tv_sec; / * seconds * / long tv_nsec; / * nanoseconds * /}

3. Select model

1. The key to the select model is to understand fd_set. For convenience of illustration, the length of fd_set is 1 byte, and every 1 bit in fd_set can correspond to a file descriptor FD. Then a 1-byte fd_set can correspond to a maximum of 8 fd.

(1) execute fd_set set; FD_ZERO (& set); then set is expressed in bits as 0000j0000.

(2) if fd=5, execute FD_SET (fd,&set); then set becomes 0001j0000 (position 5 is 1)

(3) if fd=2,fd=1 is added again, set will become 00010011.

(4) execute select (6 minutes set0 0) blocking wait

(5) if all readable events occur on the fd=1,fd=2, the select returns, and the set becomes 00000 and 0011. Note: no event fd=5 has been emptied.

2. Features:

The number of file descriptors that can be monitored depends on the value of sizeof (fd_set). If sizeof (fd_set) = 512 on the server, each bit represents a file descriptor, then the maximum file descriptor supported on the server is 5128x4096. Although adjustable, the upper limit of adjustment depends on the value of the variable when the kernel is compiled.

(2) when adding fd to the select monitoring set, we should also use a data structure array to save the fd placed in the select monitoring set. First, after the select is returned, the array is used as the source data and fd_set for FD_ISSET judgment. Second, after the return of select, the previously added fd with no event will be emptied, then the fd will be re-obtained from array one by one before starting select (FD_ZERO first), and the maximum value of fd maxfd will be obtained while scanning array, which is used for the first parameter of select.

(3) it can be seen that the select model must cycle array (add fd, take maxfd) before select, and select returns the back loop array.

(FD_ISSET judges whether there is time to happen).

4. Select server example:

# include#include#include#include#include#include#include#include#include# include#define _ BACKLOG_ 5int fds [64]; void usage (const char * proc) {printf ("% s: [ip] [port]\ n", proc);} static int startup (const char * ip,const int port) {int sock=socket (AF_INET,SOCK_STREAM,0) / / create socket if (sock < 0) {perror ("socket"); exit (1);} struct sockaddr_in local; / / fill in local information local.sin_family=AF_INET; local.sin_port=htons (port); local.sin_addr.s_addr=inet_addr (ip) If (bind (sock, (struct sockaddr*) & local,sizeof (local)) < 0) / bind {perror ("bind"); exit (2);} if (listen (sock,_BACKLOG_) < 0) / / listen {perror ("listen") Exit (3);} return sock; / / return socket} int main (int argc,char * argv []) {if (argc! = 3) {usage (argv [0]); return 1;} char * ip=argv [1]; int port=atoi (argv [2]) Int listen_sock=startup (ip,port); struct sockaddr_in client; / / create structure sockaddr_in client socklen_t len=sizeof (client); / / take its length client.sin_family=AF_INET; client.sin_port=htons (port); client.sin_addr.s_addr=inet_addr (ip); int done=0; int new_sock=-1; int max_fd / / fd_set _ reads;// readable file descriptor fd_set _ writes; / / writable file descriptor int idescriptor; int fds_num=sizeof (fds) / sizeof (fds [0]); / / the maximum length of the file descriptor for ( I max_fd) {max_fd= FDS [I] } switch (select (max_fd+1,&_reads,&_writes,NULL,&timeout)) / / select blocking wait {case-1://error perror ("select") Break; case 0://timeout printf ("select timeout...\ n"); break; default: {iTun0; for ( I 0) / / read success {buf [_ size] ='\ 0mm; printf ("Client:% s\ n", buf) } else if (_ size = = 0) / / client close {printf ("client close...\ n") Close (FDS [I]); FDS [I] =-1; break } else {perror ("read") } if (FD_ISSET (fds [I], & _ writes)) {_ size=write (FDS [I], buf) Strlen (buf)) If (_ size < 0) {perror ("write") }} else { Printf ("can't write back...\ n") }} else {} Break } return 0;}

Summary:

Every time you call select, you need to copy the fd collection from the user state to the kernel state, and every time you call select, you need to traverse all the fd passed in the kernel, resulting in too much overhead for fd.

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