Skip to content

Commit ae96beb

Browse files
committed
fix TCPServer -> v0.2.1
1 parent 330443f commit ae96beb

File tree

8 files changed

+41
-15
lines changed

8 files changed

+41
-15
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ Main functionalities:
1717
### Current version - branch master
1818

1919
[![Maven Central](https://img.shields.io/maven-central/v/net.lecousin.framework.network/core.svg)](http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22net.lecousin.framework.network%22%20AND%20a%3A%22core%22)
20-
[![Javadoc](https://img.shields.io/badge/javadoc-0.2.0-brightgreen.svg)](https://www.javadoc.io/doc/net.lecousin.framework.network/core/0.2.0)
20+
[![Javadoc](https://img.shields.io/badge/javadoc-0.2.1-brightgreen.svg)](https://www.javadoc.io/doc/net.lecousin.framework.network/core/0.2.1)
2121

2222
![build status](https://travis-ci.org/lecousin/java-framework-network-core.svg?branch=master "Build Status")
2323
![build status](https://ci.appveyor.com/api/projects/status/github/lecousin/java-framework-network-core?branch=master&svg=true "Build Status")

pom.xml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
<groupId>net.lecousin.framework.network</groupId>
1010
<artifactId>core</artifactId>
11-
<version>0.2.0</version>
11+
<version>0.2.1</version>
1212

1313
<name>lecousin.net Java framework - network - core</name>
1414
<description>Core network functionalities</description>
@@ -55,7 +55,7 @@
5555
<dependency>
5656
<groupId>net.lecousin</groupId>
5757
<artifactId>core</artifactId>
58-
<version>0.9.7</version>
58+
<version>0.9.8</version>
5959
</dependency>
6060
<dependency>
6161
<groupId>commons-logging</groupId>
@@ -77,7 +77,7 @@
7777
<dependency>
7878
<groupId>net.lecousin</groupId>
7979
<artifactId>core</artifactId>
80-
<version>0.9.7</version>
80+
<version>0.9.8</version>
8181
<type>test-jar</type>
8282
<scope>test</scope>
8383
</dependency>

src/main/java/net/lecousin/framework/network/NetworkManager.java

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
public class NetworkManager implements Closeable {
3838

3939
public static final Log logger = LogFactory.getLog("network");
40+
public static final Log dataLogger = LogFactory.getLog("network-data");
4041

4142
/**
4243
* Base interface for a listener, with a channelClosed event.
@@ -288,8 +289,25 @@ public void run() {
288289
} else {
289290
Attachment listeners = (Attachment)key.attachment();
290291
try {
291-
key.interestOps(key.interestOps() | req.newOps);
292-
listeners.set(req.newOps, req.listener, req.timeout);
292+
int curOps = key.interestOps();
293+
int conflict = curOps & req.newOps;
294+
if (conflict == 0) {
295+
key.interestOps(curOps | req.newOps);
296+
listeners.set(req.newOps, req.listener, req.timeout);
297+
} else {
298+
if ((conflict & SelectionKey.OP_ACCEPT) != 0)
299+
((Server)req.listener).acceptError(
300+
new IOException("Already registered for accept operation"));
301+
if ((conflict & SelectionKey.OP_CONNECT) != 0)
302+
((Client)req.listener).connectionFailed(
303+
new IOException("Already registered for connect operation"));
304+
if ((conflict & SelectionKey.OP_READ) != 0)
305+
((Receiver)req.listener).receiveError(
306+
new IOException("Already registered for read operation"), null);
307+
if ((conflict & SelectionKey.OP_WRITE) != 0)
308+
logger.error(
309+
new IOException("Already registered for write operation"));
310+
}
293311
} catch (CancelledKeyException e) {
294312
listeners.channelClosed();
295313
}
@@ -369,13 +387,13 @@ public void run() {
369387
tcp.endOfInput(buffer);
370388
} else {
371389
buffer.flip();
372-
if (logger.isTraceEnabled()) {
390+
if (dataLogger.isTraceEnabled()) {
373391
StringBuilder s = new StringBuilder(nb * 5 + 256);
374392
s.append(nb).append(" bytes received on ");
375393
s.append(key.channel().toString());
376394
s.append("\r\n");
377395
DebugUtil.dumpHex(s, buffer);
378-
logger.trace(s.toString());
396+
dataLogger.trace(s.toString());
379397
}
380398
if (!tcp.received(buffer)) {
381399
try {

src/main/java/net/lecousin/framework/network/client/TCPClient.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -436,12 +436,12 @@ public Void run() {
436436
public ISynchronizationPoint<IOException> send(ByteBuffer data) {
437437
if (logger.isDebugEnabled())
438438
logger.debug("Sending data: " + data.remaining());
439-
if (logger.isTraceEnabled()) {
439+
if (NetworkManager.dataLogger.isTraceEnabled()) {
440440
if (data.hasArray()) {
441441
StringBuilder s = new StringBuilder(data.remaining() * 4);
442-
s.append("Data to send:\r\n");
442+
s.append("TCPClient: Data to send to server:\r\n");
443443
DebugUtil.dumpHex(s, data.array(), data.arrayOffset() + data.position(), data.remaining());
444-
logger.trace(s.toString());
444+
NetworkManager.dataLogger.trace(s.toString());
445445
}
446446
}
447447
if (data.remaining() == 0)

src/main/java/net/lecousin/framework/network/server/TCPServer.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -239,17 +239,18 @@ synchronized SynchronizationPoint<IOException> send(ByteBuffer buf, boolean clos
239239
if (channel == null) throw new ClosedChannelException();
240240
// ask the protocol to do any needed processing before sending the data
241241
LinkedList<ByteBuffer> buffers = protocol.prepareDataToSend(publicInterface, buf);
242+
boolean waitBefore = waitToSend;
242243
if (!waitToSend) {
243244
// we can start sending data right away
244245
ByteBuffer buffer = null;
245246
while (buffer != null || !buffers.isEmpty()) {
246247
if (buffer == null)
247248
buffer = buffers.removeFirst();
248-
if (NetworkManager.logger.isTraceEnabled()) {
249+
if (NetworkManager.dataLogger.isTraceEnabled()) {
249250
StringBuilder s = new StringBuilder(128 + buffer.remaining() * 5);
250251
s.append("Sending ").append(buffer.remaining()).append(" bytes to client:\r\n");
251252
DebugUtil.dumpHex(s, buffer);
252-
NetworkManager.logger.trace(s.toString());
253+
NetworkManager.dataLogger.trace(s.toString());
253254
}
254255
int nb;
255256
try { nb = channel.write(buffer); }
@@ -280,7 +281,7 @@ synchronized SynchronizationPoint<IOException> send(ByteBuffer buf, boolean clos
280281
outputBuffers.add(new Pair<>(b, buffers.isEmpty() ? sp : null));
281282
}
282283
closeAfterLastOutput = closeAfter;
283-
if (dataToSendProvider == null)
284+
if (!waitBefore && dataToSendProvider == null)
284285
manager.register(channel, SelectionKey.OP_WRITE, this, 0);
285286
return sp;
286287
}
@@ -291,12 +292,13 @@ public void readyToSend() {
291292
@Override
292293
public Void run() {
293294
synchronized (Client.this) {
295+
if (outputBuffers == null) return null;
294296
if (outputBuffers.isEmpty() && dataToSendProvider != null) {
295297
outputBuffers.add(new Pair<>(dataToSendProvider.provide(), dataToSendSP));
296298
dataToSendProvider = null;
297299
dataToSendSP = null;
298300
}
299-
while (!outputBuffers.isEmpty()) {
301+
while (outputBuffers != null && !outputBuffers.isEmpty()) {
300302
Pair<ByteBuffer,SynchronizationPoint<IOException>> toWrite = outputBuffers.getFirst();
301303
int nb;
302304
do {
@@ -326,6 +328,7 @@ public Void run() {
326328
} while (nb > 0);
327329
if (nb == 0) break; // cannot write anymore
328330
}
331+
if (outputBuffers == null) return null;
329332
if (outputBuffers.isEmpty()) {
330333
// we are done with all data to be sent
331334
if (closeAfterLastOutput) {

src/main/java/net/lecousin/framework/network/server/protocol/ServerProtocol.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ public interface ServerProtocol {
3131
* The implementation should get the data, then process it in a separate thread/task to avoid blocking the
3232
* network manager thread.
3333
* Once the given buffer has been processed, the onbufferavailable should be called to signal the given buffer can be reused.
34+
* When calling onbufferavailable, if some data is remaining the method dataReceivedFromClient will be called again
35+
* so the implementation must ensure there is no remaining data in the buffer.
3436
* Most implementations will return false, and call the method waitForData later on, because it starts a separate
3537
* task to process the message. Because of this, if returning true, new data may arrive before the previous
3638
* task has been executed and data may be processed in a wrong order, or some concurrency issues may come in the data

src/test/java/net/lecousin/framework/network/test/AbstractNetworkTest.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ public static void initNetwork() throws Exception {
2020
// logging
2121
LoggerFactory log = LCCore.getApplication().getLoggerFactory();
2222
log.getLogger("network").setLevel(Level.TRACE);
23+
log.getLogger("network-data").setLevel(Level.TRACE);
2324
log.getLogger("SSL").setLevel(Level.TRACE);
2425
log.getLogger(TCPClient.class).setLevel(Level.TRACE);
2526
log.getLogger(SSLClient.class).setLevel(Level.TRACE);

src/test/java/net/lecousin/framework/network/tests/TestTCP.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,7 @@ public void testSSLClient() throws Exception {
232232
@Test(timeout=120000)
233233
public void testEcho() throws Exception {
234234
LCCore.getApplication().getLoggerFactory().getLogger("network").setLevel(Level.DEBUG);
235+
LCCore.getApplication().getLoggerFactory().getLogger("network-data").setLevel(Level.DEBUG);
235236
LCCore.getApplication().getLoggerFactory().getLogger(TCPClient.class).setLevel(Level.DEBUG);
236237
TCPClient client = new TCPClient();
237238
SynchronizationPoint<IOException> sp = client.connect(new InetSocketAddress("localhost", 9997), 10000, new SocketOptionValue<>(StandardSocketOptions.SO_SNDBUF, Integer.valueOf(512)));
@@ -245,6 +246,7 @@ public void testEcho() throws Exception {
245246
Assert.assertArrayEquals(data, client.getReceiver().readBytes(data.length, 10000).blockResult(0));
246247
client.close();
247248
LCCore.getApplication().getLoggerFactory().getLogger(TCPClient.class).setLevel(Level.TRACE);
249+
LCCore.getApplication().getLoggerFactory().getLogger("network-data").setLevel(Level.TRACE);
248250
LCCore.getApplication().getLoggerFactory().getLogger("network").setLevel(Level.TRACE);
249251
}
250252

0 commit comments

Comments
 (0)