Skip to content

Commit 7a9a69b

Browse files
MajewskiKrzysztofkrzysztof
andauthored
BAEL-5076 Unix domain socket in Java 16 (eugenp#11493)
* BAEL-5076 Unix domain socket in Java 16 * BAEL-5076 Unix domain socket in Java 16 * BAEL-5076 Unix domain socket in Java 16 * BAEL-5076 Unix domain socket in Java 16 Co-authored-by: krzysztof <[email protected]>
1 parent 9f1f4cb commit 7a9a69b

7 files changed

Lines changed: 250 additions & 1 deletion

File tree

core-java-modules/core-java-networking-3/pom.xml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,16 @@
6464
</plugin>
6565
</plugins>
6666
</pluginManagement>
67+
<plugins>
68+
<plugin>
69+
<groupId>org.apache.maven.plugins</groupId>
70+
<artifactId>maven-compiler-plugin</artifactId>
71+
<configuration>
72+
<source>16</source>
73+
<target>16</target>
74+
</configuration>
75+
</plugin>
76+
</plugins>
6777
</build>
6878

6979
<properties>
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package com.baeldung.socket;
2+
3+
import java.io.IOException;
4+
import java.net.StandardProtocolFamily;
5+
import java.net.UnixDomainSocketAddress;
6+
import java.nio.ByteBuffer;
7+
import java.nio.channels.SocketChannel;
8+
import java.nio.file.Path;
9+
10+
class UnixDomainSocketClient {
11+
12+
public static void main(String[] args) throws Exception {
13+
new UnixDomainSocketClient().runClient();
14+
}
15+
16+
void runClient() throws IOException {
17+
Path socketPath = Path.of(System.getProperty("user.home"))
18+
.resolve("baeldung.socket");
19+
UnixDomainSocketAddress socketAddress = getAddress(socketPath);
20+
21+
SocketChannel channel = openSocketChannel(socketAddress);
22+
23+
String message = "Hello from Baeldung Unix domain socket article";
24+
writeMessage(channel, message);
25+
}
26+
27+
UnixDomainSocketAddress getAddress(Path socketPath) {
28+
return UnixDomainSocketAddress.of(socketPath);
29+
}
30+
31+
SocketChannel openSocketChannel(UnixDomainSocketAddress socketAddress) throws IOException {
32+
SocketChannel channel = SocketChannel
33+
.open(StandardProtocolFamily.UNIX);
34+
channel.connect(socketAddress);
35+
return channel;
36+
}
37+
38+
void writeMessage(SocketChannel socketChannel, String message) throws IOException {
39+
ByteBuffer buffer = ByteBuffer.allocate(1024);
40+
buffer.clear();
41+
buffer.put(message.getBytes());
42+
buffer.flip();
43+
44+
while (buffer.hasRemaining()) {
45+
socketChannel.write(buffer);
46+
}
47+
}
48+
49+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package com.baeldung.socket;
2+
3+
import java.io.IOException;
4+
import java.net.StandardProtocolFamily;
5+
import java.net.UnixDomainSocketAddress;
6+
import java.nio.ByteBuffer;
7+
import java.nio.channels.ServerSocketChannel;
8+
import java.nio.channels.SocketChannel;
9+
import java.nio.file.Files;
10+
import java.nio.file.Path;
11+
import java.util.Optional;
12+
13+
class UnixDomainSocketServer {
14+
15+
public static void main(String[] args) throws IOException, InterruptedException {
16+
new UnixDomainSocketServer().runServer();
17+
}
18+
19+
void runServer() throws IOException, InterruptedException {
20+
Path socketPath = Path.of(System.getProperty("user.home"))
21+
.resolve("baeldung.socket");
22+
Files.deleteIfExists(socketPath);
23+
UnixDomainSocketAddress socketAddress = getAddress(socketPath);
24+
25+
ServerSocketChannel serverChannel = createServerSocketChannel(socketAddress);
26+
27+
SocketChannel channel = serverChannel.accept();
28+
29+
while (true) {
30+
readSocketMessage(channel)
31+
.ifPresent(message -> System.out.printf("[Client message] %s%n", message));
32+
Thread.sleep(100);
33+
}
34+
}
35+
36+
UnixDomainSocketAddress getAddress(Path socketPath) {
37+
return UnixDomainSocketAddress.of(socketPath);
38+
}
39+
40+
ServerSocketChannel createServerSocketChannel(UnixDomainSocketAddress socketAddress) throws IOException {
41+
ServerSocketChannel serverChannel = ServerSocketChannel.open(StandardProtocolFamily.UNIX);
42+
serverChannel.bind(socketAddress);
43+
return serverChannel;
44+
}
45+
46+
Optional<String> readSocketMessage(SocketChannel channel) throws IOException {
47+
ByteBuffer buffer = ByteBuffer.allocate(1024);
48+
int bytesRead = channel.read(buffer);
49+
if (bytesRead < 0) return Optional.empty();
50+
byte[] bytes = new byte[bytesRead];
51+
buffer.flip();
52+
buffer.get(bytes);
53+
String message = new String(bytes);
54+
return Optional.of(message);
55+
}
56+
57+
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
package com.baeldung.socket;
2+
3+
import org.junit.Test;
4+
import org.mockito.Mockito;
5+
import org.mockito.stubbing.Answer;
6+
7+
import java.io.File;
8+
import java.io.IOException;
9+
import java.net.StandardProtocolFamily;
10+
import java.net.UnixDomainSocketAddress;
11+
import java.nio.ByteBuffer;
12+
import java.nio.channels.ServerSocketChannel;
13+
import java.nio.channels.SocketChannel;
14+
import java.nio.file.Path;
15+
import java.util.UUID;
16+
17+
import static java.nio.file.Files.deleteIfExists;
18+
import static org.assertj.core.util.Files.newTemporaryFile;
19+
import static org.junit.Assert.assertEquals;
20+
import static org.junit.Assert.assertTrue;
21+
22+
public class UnixDomainSocketClientUnitTest {
23+
24+
@Test
25+
public void givenSocketPath_shouldCreateUnixDomainSocketAddress() {
26+
// given
27+
File tempFile = newTemporaryFile();
28+
Path socketPath = tempFile.toPath();
29+
30+
// when
31+
UnixDomainSocketAddress address = new UnixDomainSocketClient().getAddress(socketPath);
32+
33+
// then
34+
assertEquals(address.getPath(), socketPath);
35+
36+
// cleanup
37+
tempFile.delete();
38+
}
39+
40+
@Test
41+
public void givenUnixDomainSocketAddress_shouldOpenSocketChannel() throws IOException {
42+
// given
43+
File tempFile = newTemporaryFile();
44+
Path socketPath = tempFile.toPath();
45+
deleteIfExists(socketPath);
46+
UnixDomainSocketAddress address = UnixDomainSocketAddress.of(socketPath);
47+
48+
// bind address as a unix domain socket
49+
ServerSocketChannel serverChannel = ServerSocketChannel.open(StandardProtocolFamily.UNIX);
50+
serverChannel.bind(address);
51+
52+
// when
53+
SocketChannel socketChannel = new UnixDomainSocketClient().openSocketChannel(address);
54+
55+
// then
56+
assertTrue(socketChannel.isOpen());
57+
assertEquals(socketChannel.getRemoteAddress(), address);
58+
59+
// cleanup
60+
tempFile.delete();
61+
}
62+
63+
@Test
64+
public void givenSocketChannelAndMessage_shouldWriteMessage() throws IOException {
65+
// given
66+
SocketChannel socketChannel = Mockito.mock(SocketChannel.class);
67+
String message = UUID.randomUUID().toString();
68+
Mockito.when(socketChannel.write(Mockito.any(ByteBuffer.class)))
69+
.thenAnswer(
70+
(Answer<Integer>) invocationOnMock -> {
71+
((ByteBuffer) invocationOnMock.getArguments()[0]).position(message.getBytes().length);
72+
return -1;
73+
}
74+
);
75+
76+
// when
77+
new UnixDomainSocketClient().writeMessage(socketChannel, message);
78+
79+
// then
80+
Mockito.verify(socketChannel, Mockito.times(1)).write(Mockito.any(ByteBuffer.class));
81+
}
82+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package com.baeldung.socket;
2+
3+
import org.junit.Test;
4+
5+
import java.io.File;
6+
import java.io.IOException;
7+
import java.net.UnixDomainSocketAddress;
8+
import java.nio.channels.ServerSocketChannel;
9+
import java.nio.file.Path;
10+
11+
import static java.nio.file.Files.deleteIfExists;
12+
import static org.assertj.core.util.Files.newTemporaryFile;
13+
import static org.junit.Assert.assertEquals;
14+
15+
public class UnixDomainSocketServerUnitTest {
16+
17+
@Test
18+
public void givenSocketPath_shouldCreateUnixDomainSocketAddress() {
19+
// given
20+
File tempFile = newTemporaryFile();
21+
Path socketPath = tempFile.toPath();
22+
23+
// when
24+
UnixDomainSocketAddress address = new UnixDomainSocketServer().getAddress(socketPath);
25+
26+
// then
27+
assertEquals(address.getPath(), socketPath);
28+
29+
// cleanup
30+
tempFile.delete();
31+
}
32+
33+
@Test
34+
public void givenUnixDomainSocketAddress_shouldCreateServerSocketChannel() throws IOException {
35+
// given
36+
File tempFile = newTemporaryFile();
37+
Path socketPath = tempFile.toPath();
38+
deleteIfExists(socketPath);
39+
UnixDomainSocketAddress address = UnixDomainSocketAddress.of(socketPath);
40+
41+
// when
42+
ServerSocketChannel serverSocketChannel = new UnixDomainSocketServer().createServerSocketChannel(address);
43+
44+
// then
45+
assertEquals(serverSocketChannel.getLocalAddress(), address);
46+
47+
// cleanup
48+
tempFile.delete();
49+
}
50+
}

core-java-modules/pom.xml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,6 @@
9090
<module>core-java-lang-syntax-2</module>
9191
<module>core-java-networking</module>
9292
<module>core-java-networking-2</module>
93-
<module>core-java-networking-3</module>
9493
<module>core-java-nio</module>
9594
<module>core-java-nio-2</module>
9695
<module>core-java-optional</module>

pom.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1322,6 +1322,7 @@
13221322
<module>core-java-modules/core-java-string-operations-3</module>
13231323
<module>core-java-modules/core-java-string-operations-4</module>
13241324
<module>core-java-modules/core-java-time-measurements</module>
1325+
<module>core-java-modules/core-java-networking-3</module>
13251326
<module>core-java-modules/multimodulemavenproject</module>
13261327
<module>persistence-modules/sirix</module>
13271328
<module>quarkus-vs-springboot</module>
@@ -1375,6 +1376,7 @@
13751376
<module>core-java-modules/core-java-os</module>
13761377
<module>core-java-modules/core-java-string-operations-3</module>
13771378
<module>core-java-modules/core-java-time-measurements</module>
1379+
<module>core-java-modules/core-java-networking-3</module>
13781380
<module>core-java-modules/multimodulemavenproject</module>
13791381
<module>core-java-modules/core-java-strings</module>
13801382
<module>persistence-modules/sirix</module>

0 commit comments

Comments
 (0)