11
11
import java .nio .channels .SelectionKey ;
12
12
import java .nio .channels .Selector ;
13
13
import java .nio .channels .SocketChannel ;
14
- import java .util .concurrent .TimeUnit ;
14
+ import java .time .Duration ;
15
+ import java .time .temporal .ChronoUnit ;
15
16
16
17
final class TCPClient {
17
- private final long endTime ;
18
+ private final long startTime ;
19
+ private final Duration timeout ;
18
20
private final SelectionKey key ;
19
21
20
- TCPClient (long timeout ) throws IOException {
21
- endTime = System .nanoTime () + TimeUnit .MILLISECONDS .toNanos (timeout );
22
+ TCPClient (Duration timeout ) throws IOException {
23
+ this .timeout = timeout ;
24
+ startTime = System .nanoTime ();
22
25
boolean done = false ;
23
26
Selector selector = null ;
24
27
SocketChannel channel = SocketChannel .open ();
@@ -51,7 +54,7 @@ void connect(SocketAddress addr) throws IOException {
51
54
try {
52
55
while (!channel .finishConnect ()) {
53
56
if (!key .isConnectable ()) {
54
- blockUntil (key , endTime );
57
+ blockUntil (key );
55
58
}
56
59
}
57
60
} finally {
@@ -84,11 +87,11 @@ void send(byte[] data) throws IOException {
84
87
throw new EOFException ();
85
88
}
86
89
nsent += (int ) n ;
87
- if (nsent < data .length + 2 && endTime - System .nanoTime () < 0 ) {
90
+ if (nsent < data .length + 2 && System .nanoTime () - startTime >= timeout . toNanos () ) {
88
91
throw new SocketTimeoutException ();
89
92
}
90
93
} else {
91
- blockUntil (key , endTime );
94
+ blockUntil (key );
92
95
}
93
96
}
94
97
} finally {
@@ -112,11 +115,11 @@ private byte[] _recv(int length) throws IOException {
112
115
throw new EOFException ();
113
116
}
114
117
nrecvd += (int ) n ;
115
- if (nrecvd < length && System .currentTimeMillis () > endTime ) {
118
+ if (nrecvd < length && System .nanoTime () - startTime >= timeout . toNanos () ) {
116
119
throw new SocketTimeoutException ();
117
120
}
118
121
} else {
119
- blockUntil (key , endTime );
122
+ blockUntil (key );
120
123
}
121
124
}
122
125
} finally {
@@ -127,12 +130,13 @@ private byte[] _recv(int length) throws IOException {
127
130
return data ;
128
131
}
129
132
130
- private static void blockUntil (SelectionKey key , long endTime ) throws IOException {
131
- long timeout = TimeUnit .NANOSECONDS .toMillis (endTime - System .nanoTime ());
133
+ private void blockUntil (SelectionKey key ) throws IOException {
134
+ long remainingTimeout =
135
+ timeout .minus (System .nanoTime () - startTime , ChronoUnit .NANOS ).toMillis ();
132
136
int nkeys = 0 ;
133
- if (timeout > 0 ) {
134
- nkeys = key .selector ().select (timeout );
135
- } else if (timeout == 0 ) {
137
+ if (remainingTimeout > 0 ) {
138
+ nkeys = key .selector ().select (remainingTimeout );
139
+ } else if (remainingTimeout == 0 ) {
136
140
nkeys = key .selector ().selectNow ();
137
141
}
138
142
if (nkeys == 0 ) {
0 commit comments