当在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