大家好,又见面了,我是你们的朋友全栈君。
当在ioctl里使用FIONREAD时,除了获得所指定的读缓存大小以外,还有清除设备准备就绪状态的作用.
代码
#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时测试结果也是如此:
代码
/*
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账号...