关于FIONREAD命令的作用[通俗易懂]

关于FIONREAD命令的作用[通俗易懂]当在ioctl里使用FIONREAD时,除了获得所指定的读缓存大小以外,还有清除设备准备就绪状态的作用.代码CodehighlightingproducedbyActiproCodeHig

大家好,又见面了,我是你们的朋友全栈君。

当在ioctl里使用FIONREAD时,除了获得所指定的读缓存大小以外,还有清除设备准备就绪状态的作用.

 

关于FIONREAD命令的作用[通俗易懂]
关于FIONREAD命令的作用[通俗易懂]
代码

 1 
#include 
<
sys
/
types.h
>


 2 
#include 
<
sys
/
time.h
>


 3 
#include 
<
stdio.h
>


 4 
#include 
<
fcntl.h
>


 5 
#include 
<
sys
/
ioctl.h
>


 6 
#include 
<
unistd.h
>


 7 


 8 

int
 main(
int
 argc, 
char
*
 argv[])

 9 
{

10 
    
int
 debug 
=
 
0
;

11 
    
char
 buffer[
128
];

12 
    
int
 result, nread;

13 
    fd_set inputs, testfds;

14 
    
struct
 timeval timeout;

15 
    
int
 status;

16 
    
int
*
 ptr 
=
 
&
inputs;

17 
    

18 
    FD_ZERO(
&
inputs);

19 
    printf(

—————–before SET—–%d———–\n


*
ptr);

20 
    FD_SET(
0

&
inputs);

21 
    printf(

—————–after SET—–%d———–\n


*
ptr);

22 
    

23 
    

24 
    
while
(
1
)

25 
    {

26 
        

27 
        timeout.tv_sec 
=
 
2
;

28 
        timeout.tv_usec 
=
 
500000
;

29 
        

30 
        testfds 
=
 inputs;

31 
        ptr 
=
 
&
testfds;

32 
        result 
=
 select(FD_SETSIZE, 
&
testfds, (fd_set
*
)NULL,

33 
                                        (fd_set
*
)NULL, 
/*
&timeout
*/
0
);

34 
        printf(

==========================================\n

);                                        

35 
        

36 
        sleep(
4
);

37 
        
switch
(result)

38 
        {

39 
            
case
 
0
:

40 
                printf(

timeout \n

);

41 
                debug 
=
 FD_ISSET(
0

&
testfds);

42 
                printf(

t—————–before SET—–%d—-FD_SET–%d—–\n


*
ptr, debug );

43 
                
break
;

44 
            
case
 

1
:

45 
                perror(

select\n

);

46 
                exit(
1
);

47 
            
default
:

48 
                
if
(FD_ISSET(
0

&
testfds))

49 
                    {

50 
                        printf(

1—————–before SET—–%d———–\n


*
ptr);

51 
                        
//
ioctl(0, FIONREAD, &nread);


52 

                        
if
(
0
 
==
 nread)

53 
                            {

54 
                                printf(

keyboard done \n

);

55 
                                exit(
0
);

56 
                            }

57 
                            printf(

———–result–%d———-\n

, result);

58 
                            nread 
=
 read(
0
, buffer, nread);

59 
                            buffer[nread] 
=
 
0
;

60 
                            printf(

read %d from keyboard: %s\n

, nread, buffer);

61 
                            

62 
                            printf(

1—————–after SET—–%d———–\n


*
ptr);

63 
                    }

64 
                
break
;

65 
        }

66 
        

67 
    }

68 
    
return
 
0
;

69 
}

70 
 

 

 

当51行注释以后, 由于各个设备的状态未被清除,所以循环一直处于非阻塞的状态.不停的打印一个状态(即未清除状态)的信息.

如果不注释ioctl,那么select会自动清除未准备好的设备状态. 此时阻塞是有效地.

 

同样的,在socket当中使用select和ioctl时测试结果也是如此:

 

关于FIONREAD命令的作用[通俗易懂]
关于FIONREAD命令的作用[通俗易懂]
代码

  1 
/*
  For our final example, server5.c, 

  2 
    we include the sys/time.h and sys/ioctl.h headers in place of signal.h

  3 
    in our last program and declare some extra variables to deal with select.  
*/


  4 


  5 
#include 
<
sys
/
types.h
>


  6 
#include 
<
sys
/
socket.h
>


  7 
#include 
<
stdio.h
>


  8 
#include 
<
netinet
/
in
.h
>


  9 
#include 
<
sys
/
time.h
>


 10 
#include 
<
sys
/
ioctl.h
>


 11 
#include 
<
unistd.h
>


 12 


 13 

int
 main()

 14 
{

 15 
    FILE
*
 fp;

 16 
    
int
 i
=
0
;

 17 
    
int
 count 
=
 
0
;

 18 
    
int
 server_sockfd, client_sockfd;

 19 
    
int
 server_len, client_len;

 20 
    
struct
 sockaddr_in server_address;

 21 
    
struct
 sockaddr_in client_address;

 22 
    
int
 result;

 23 
    fd_set readfds, testfds;

 24 


 25 

/*
  Create and name a socket for the server.  
*/


 26 


 27 
    server_sockfd 
=
 socket(AF_INET, SOCK_STREAM, 
0
);

 28 


 29 
    server_address.sin_family 
=
 AF_INET;

 30 
    server_address.sin_addr.s_addr 
=
 htonl(INADDR_ANY);

 31 
    server_address.sin_port 
=
 htons(
9734
);

 32 
    server_len 
=
 
sizeof
(server_address);

 33 


 34 
    bind(server_sockfd, (
struct
 sockaddr 
*
)
&
server_address, server_len);

 35 


 36 

/*
  Create a connection queue and initialize readfds to handle input from server_sockfd.  
*/


 37 


 38 
    listen(server_sockfd, 
5
);

 39 
  printf(

—————–server_socket———-%d———-\n

, server_sockfd);

 40 


 41 
    FD_ZERO(
&
readfds);

 42 
    FD_SET(server_sockfd, 
&
readfds);

 43 
    

 44 
    
if
(FD_ISSET(server_sockfd, 
&
readfds))

 45 
    {

 46 
        printf(

fds hit!\n

);

 47 
    }

 48 


 49 

/*
  Now wait for clients and requests.

 50 
    Since we have passed a null pointer as the timeout parameter, no timeout will occur.

 51 
    The program will exit and report an error if select returns a value of less than 1.  
*/


 52 


 53 
    
while
(
1
) {

 54 
        
char
 ch;

 55 
        
int
 fd;

 56 
        
int
 nread;

 57 


 58 
        testfds 
=
 readfds;

 59 
        

 60 
        printf(

server waiting\n

);

 61 
        result 
=
 select(FD_SETSIZE, 
&
testfds, (fd_set 
*
)
0


 62 
            (fd_set 
*
)
0
, (
struct
 timeval 
*

0
);

 63 


 64 
        
if
(result 
<
 
1
) {

 65 
            perror(

server5

);

 66 
   
//
         return 0;


 67 

        }

 68 
        

 69 
        

 70 
        

 71 
        printf(

\\\\\\\\%d——–result—%d–\n

, count, result);

 72 
               

 73 


 74 

/*
  Once we know we’ve got activity,

 75 
    we find which descriptor it’s on by checking each in turn using FD_ISSET.  
*/


 76 
            count
++
;

 77 
            fp 
=
 fopen(

count.txt



ab+

);

 78 
                    
for
( i
=
0
; i 
<
 FD_SETSIZE; i
++
)

 79 
                    {

 80 
                        
if
(FD_ISSET(i, 
&
testfds))

 81 
                            fprintf(fp, 

testfds ## count–%d——i:—-%d——-\n

, count, i);

 82 
                        
if
(FD_ISSET(i, 
&
readfds))

 83 
                            fprintf(fp, 

readfds ## count–%d——i:—-%d——-\n

, count, i);

 84 
                    }

 85 
                    fprintf(fp, 

\n

);

 86 
                    fclose(fp);

 87 
                    

 88 
                    

 89 
        
for
(fd 
=
 
0
; fd 
<
 FD_SETSIZE; fd
++
) {

 90 
            
//
printf(“count++++%d+++++++++++++++++++fd+++%d+++++++++++++++\n”, count, fd);


 91 

            
if
(FD_ISSET(fd,
&
testfds)) {

 92 


 93 

/*
  If the activity is on server_sockfd, it must be a request for a new connection

 94 
    and we add the associated client_sockfd to the descriptor set.  
*/


 95 
                            

 96 
                            printf(

*****count*******%d******************fd******%d***********\n

, count, fd);

 97 


 98 
                
if
(fd 
==
 server_sockfd) {

 99 
                    client_len 
=
 
sizeof
(client_address);

100 
                    client_sockfd 
=
 accept(server_sockfd, 

101 
                        (
struct
 sockaddr 
*
)
&
client_address, 
&
client_len);

102 
                    

103 
                    FD_SET(client_sockfd, 
&
readfds);

104 
                    

105 
               fp 
=
 fopen(

debug.txt



ab+

);

106 
                    
for
( i
=
0
; i 
<
 FD_SETSIZE; i
++
)

107 
                    {

108 
                        
if
(FD_ISSET(i, 
&
readfds))

109 
                            fprintf(fp, 

serv ## count–%d——i:—-%d——-\n

, count, i);

110 
                    }

111 
                    fprintf(fp, 

———–serv—————\n

);

112 
                    fclose(fp);

113 
                    

114 
                    printf(

adding client on fd %d\n

, client_sockfd);

115 
                }

116 


117 

/*
  If it isn’t the server, it must be client activity.

118 
    If close is received, the client has gone away and we remove it from the descriptor set.

119 
    Otherwise, we ‘serve’ the client as in the previous examples.  
*/


120 


121 
                
else
 {

122 
                    fp 
=
 fopen(

debug.txt



ab+

);

123 
                    
for
( i
=
0
; i 
<
 FD_SETSIZE; i
++
)

124 
                    {

125 
                        
if
(FD_ISSET(i, 
&
readfds))

126 
                            fprintf(fp, 

before ## count–%d——i:—-%d——-\n

, count, i);

127 
                    }

128 
                    fprintf(fp, 

———–before—————\n

);

129 
                    fclose(fp);

130 
                    

131 
                 
//
 ioctl(fd, FIONREAD, &nread);


132 

                    

133 
                    

134 


135 
                    
if
(nread 
==
 
0
) {

136 
                        close(fd);

137 
                        FD_CLR(fd, 
&
readfds);

138 
                        printf(

removing client on fd %d\n

, fd);

139 
                    }

140 


141 
                    
else
 {

142 
                        read(fd, 
&
ch, 
1
);

143 
                        sleep(
5
);

144 
                        printf(

serving client on fd %d\n

, fd);

145 
                        ch
++
;

146 
                      
//
write(fd, &ch, 1);


147 

                                                printf(

serving 000on fd %d\n

, fd);

148 
                    }

149 
                    

150 
                    fp 
=
 fopen(

debug.txt



ab+

);

151 
                    
for
(i
=
0
; i 
<
 FD_SETSIZE; i
++
)

152 
                    {

153 
                        
if
(FD_ISSET(i, 
&
readfds))

154 
                            fprintf(fp, 

after ## count–%d——i:—-%d——-\n

, count, i);

155 
                    }

156 
                    fclose(fp);

157 
                }

158 
                fp 
=
 fopen(

debug.txt



ab+

);

159 
                    fprintf(fp, 

\n\n

);

160 
                    fclose(fp);

161 
            }

162 
        }

163 
    }

164 
}

165 

 

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/155030.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号