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

发布时间:2025-12-09 14:07:46 浏览次数:4

当在ioctl里使用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_setinputs,testfds;

14

struct
timevaltimeout;

15

int
status;

16

int
*
ptr
=

&
inputs;

17


18
FD_ZERO(
&
inputs);

19
printf(

—————–beforeSET—–%d———–\n

,
*
ptr);

20
FD_SET(
0
,
&
inputs);

21
printf(

—————–afterSET—–%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—————–beforeSET—–%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—————–beforeSET—–%d———–\n

,
*
ptr);

51

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


52


if
(
0

==
nread)

53
{

54
printf(

keyboarddone\n

);

55
exit(
0
);

56
}

57
printf(

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

,result);

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

59
buffer[nread]
=

0
;

60
printf(

read%dfromkeyboard:%s\n

,nread,buffer);

61


62
printf(

1—————–afterSET—–%d———–\n

,
*
ptr);

63
}

64

break
;

65
}

66


67
}

68

return

0
;

69
}

70

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

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

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



代码

1
/*
Forourfinalexample,server5.c,

2
weincludethesys/time.handsys/ioctl.hheadersinplaceofsignal.h

3
inourlastprogramanddeclaresomeextravariablestodealwithselect.
*/


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_inserver_address;

21

struct
sockaddr_inclient_address;

22

int
result;

23
fd_setreadfds,testfds;

24


25

/*
Createandnameasocketfortheserver.
*/


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

/*
Createaconnectionqueueandinitializereadfdstohandleinputfromserver_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(

fdshit!\n

);

47
}

48


49

/*
Nowwaitforclientsandrequests.

50
Sincewehavepassedanullpointerasthetimeoutparameter,notimeoutwilloccur.

51
Theprogramwillexitandreportanerrorifselectreturnsavalueoflessthan1.
*/


52


53

while
(
1
){

54

char
ch;

55

int
fd;

56

int
nread;

57


58
testfds
=
readfds;

59


60
printf(

serverwaiting\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

//
return0;


67

}

68


69


70


71
printf(

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

,count,result);

72


73


74

/*
Onceweknowwe’vegotactivity,

75
wefindwhichdescriptorit’sonbycheckingeachinturnusingFD_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

/*
Iftheactivityisonserver_sockfd,itmustbearequestforanewconnection

94
andweaddtheassociatedclient_sockfdtothedescriptorset.
*/


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(

addingclientonfd%d\n

,client_sockfd);

115
}

116


117

/*
Ifitisn’ttheserver,itmustbeclientactivity.

118
Ifcloseisreceived,theclienthasgoneawayandweremoveitfromthedescriptorset.

119
Otherwise,we‘serve’theclientasinthepreviousexamples.
*/


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(

removingclientonfd%d\n

,fd);

139
}

140


141

else
{

142
read(fd,
&
ch,
1
);

143
sleep(
5
);

144
printf(

servingclientonfd%d\n

,fd);

145
ch
++
;

146

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


147

printf(

serving000onfd%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

需要做网站?需要网络推广?欢迎咨询客户经理 13272073477