Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Separation of concerns and simpler API #2

Merged
merged 4 commits into from almost 3 years ago

3 participants

Steven Collins Nicolas Botzet Urs Reupke
Steven Collins

judp can now be used like this:

public class IntegrationTest {

     private static final int PORT = 8123;
     private static final String EXPECTED = "expected";
     private final JudpReceiver receiver = new JudpReceiver(PORT);
     private final JudpSender sender = new JudpSender("127.0.0.1", PORT);
     

     @Test
     public void receivesWithDefaultPacketSize() throws Exception {
        sender.send(EXPECTED);
     
        assertEquals(EXPECTED, receiver.receive());
     }

     @Test
     public void receivesNotFullStringWhenPacketSizeTooSmall() throws Exception {
        sender.send(EXPECTED);
     
        assertFalse(EXPECTED.equals(receiver.receive(2)));
     }

     @After
     public void closeSockets() {
        receiver.close();
        sender.close();
     }
}
Urs Reupke

Hey @lomin,
what's the benefit of declaring the serialVersionUIDs on the Exceptions (and only there), instead of just leaning on the compiler?
Is there something about RuntimeExceptions (or the context of UDP) and serialization that requires them?

Hi @UrsKR,

I always follow this advice when my classes implement java.io.Serializable:

http://stackoverflow.com/questions/285793/why-should-i-bother-about-serialversionuid/285809#285809

It might not be necessary in this context, but if I had to change the class later, I had to do this (and that would be too much effort):

http://stackoverflow.com/questions/285793/why-should-i-bother-about-serialversionuid/285827#285827

Thanks, I figured as much.

I wouldn't expect the exceptions to ever be serialized, so I don't think it matters here.
On the other hand, they probably won't change either, so the usual point about having to stay vigilant to manually change the UID doesn't apply here.

Just so you know why I'm asking, I had a similiar discussion over at the Anathema project and started to wonder whether I missed something.
Generally speaking, I prefer to lean on the compiler. Most code I deal with doesn't require serialization at all - as does yours here.
Even if it does need it, most projects use the same compiler to build client and server code, and require their versions to be identical on top of that.

Nicolas Botzet nbotzet merged commit 9a05f93 into from
Nicolas Botzet
Owner
Urs Reupke

This line still has me guessing.
Your test shows it doesn't work in any simpler form (e.g. new String(datagramPacket.getData()), but why?
Can you help me out, @lomin?

Got it. (I guess.)
The DatagramPacket has bytes of data equal to the packetSize, but it's length equals the number of bytes that are actually filled with content.

 return new String(datagramPacket.getData()).trim();

yields the same result.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
8 .classpath
... ... @@ -0,0 +1,8 @@
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<classpath>
  3 + <classpathentry kind="src" path="src"/>
  4 + <classpathentry kind="src" path="test"/>
  5 + <classpathentry kind="output" path="bin"/>
  6 + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER" exported="true"/>
  7 + <classpathentry sourcepath="/home/steven/.gradle/cache/junit/junit/sources/junit-4.7-sources.jar" kind="lib" path="/home/steven/.gradle/cache/junit/junit/jars/junit-4.7.jar" exported="true"/>
  8 +</classpath>
5 .gitignore
... ... @@ -0,0 +1,5 @@
  1 +*.class
  2 +bin
  3 +build
  4 +.settings
  5 +.gradle
17 .project
... ... @@ -0,0 +1,17 @@
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<projectDescription>
  3 + <links/>
  4 + <name>judp</name>
  5 + <comment/>
  6 + <projects/>
  7 + <natures>
  8 + <nature>org.eclipse.jdt.core.javanature</nature>
  9 + </natures>
  10 + <buildSpec>
  11 + <buildCommand>
  12 + <name>org.eclipse.jdt.core.javabuilder</name>
  13 + <arguments/>
  14 + </buildCommand>
  15 + </buildSpec>
  16 + <linkedResources/>
  17 +</projectDescription>
56 README.md
Source Rendered
@@ -4,28 +4,34 @@ Java UDP
4 4 This library provides a helpful abstraction over Java's built in UDP handling.
5 5
6 6
7   -Usage
8   ---------
9   -
10   -Create a
11   -
12   - JUDP judp = new JUDP();
13   -
14   -and initialize it with
15   -
16   - judp.start(inetAdress, serverport, clientport);
17   -
18   -where inetAdress is the IP adress of the server you want to talk to,
19   -serverport is the port you wand to send to,
20   -and clientport is the port you want to listen on.
21   -
22   -Use
23   -
24   - judp.receive()
25   -
26   -to get an incoming package (best used in a running loop)
27   -and
28   -
29   - judp.send(message)
30   -
31   -to send the String "message" to the server.
  7 +See the IntegrationTest for Usage:
  8 +<pre>
  9 +public class IntegrationTest {
  10 +
  11 + private static final int PORT = 8123;
  12 + private static final String EXPECTED = "expected";
  13 + private final JudpReceiver receiver = new JudpReceiver(PORT);
  14 + private final JudpSender sender = new JudpSender("127.0.0.1", PORT);
  15 +
  16 +
  17 + @Test
  18 + public void receivesWithDefaultPacketSize() throws Exception {
  19 + sender.send(EXPECTED);
  20 +
  21 + assertEquals(EXPECTED, receiver.receive());
  22 + }
  23 +
  24 + @Test
  25 + public void receivesNotFullStringWhenPacketSizeTooSmall() throws Exception {
  26 + sender.send(EXPECTED);
  27 +
  28 + assertFalse(EXPECTED.equals(receiver.receive(2)));
  29 + }
  30 +
  31 + @After
  32 + public void closeSockets() {
  33 + receiver.close();
  34 + sender.close();
  35 + }
  36 +}
  37 +</pre>
30 build.gradle
... ... @@ -0,0 +1,30 @@
  1 +apply plugin: 'java'
  2 +apply plugin: 'eclipse'
  3 +
  4 +sourceCompatibility=1.6
  5 +targetCompatibility=1.6
  6 +
  7 +version='1.0.0'
  8 +
  9 +defaultTasks 'clean', 'build'
  10 +
  11 +repositories {
  12 + mavenCentral()
  13 +}
  14 +
  15 +dependencies {
  16 + testCompile group: 'junit', name: 'junit', version: '4.7'
  17 +}
  18 +
  19 +sourceSets {
  20 + main {
  21 + java {
  22 + srcDir 'src'
  23 + }
  24 + }
  25 + test {
  26 + java {
  27 + srcDir 'test'
  28 + }
  29 + }
  30 +}
BIN  judp.jar
Binary file not shown
22 src/de/itagile/judp/DatagramSocketFactory.java
... ... @@ -0,0 +1,22 @@
  1 +package de.itagile.judp;
  2 +
  3 +import java.net.DatagramSocket;
  4 +
  5 +public class DatagramSocketFactory {
  6 +
  7 + public static DatagramSocket create() {
  8 + try {
  9 + return new DatagramSocket();
  10 + } catch (java.net.SocketException e) {
  11 + throw new SocketException(e);
  12 + }
  13 + }
  14 +
  15 + public static DatagramSocket create(int port) {
  16 + try {
  17 + return new DatagramSocket(port);
  18 + } catch (java.net.SocketException e) {
  19 + throw new SocketException(e);
  20 + }
  21 + }
  22 +}
39 src/de/itagile/judp/Judp.java
... ... @@ -1,43 +1,20 @@
1 1 package de.itagile.judp;
2 2
3   -import java.net.DatagramPacket;
4 3 import java.net.DatagramSocket;
5   -import java.net.InetAddress;
6 4
7 5 public class Judp {
8   - private InetAddress ip;
9   - private int serverPort;
10   - private DatagramSocket serverSocket;
11   - private DatagramSocket clientSocket;
12 6
13   - public static void main(String[] args) throws Exception {
14   - Judp updServer = new Judp();
15   - updServer.start(InetAddress.getByName(args[0]), (int) new Integer(
16   - args[1]), (int) new Integer(args[2]));
17   - System.out.println(updServer.receive());
18   - }
  7 + private final DatagramSocket socket;
19 8
20   - public void start(InetAddress ip, int serverPort, int clientPort)
21   - throws Exception {
22   - this.ip = ip;
23   - this.serverPort = serverPort;
24   - serverSocket = new DatagramSocket();
25   - clientSocket = new DatagramSocket(clientPort);
26   - clientSocket.setSoTimeout(2000);
  9 + public Judp(DatagramSocket socket) {
  10 + this.socket = socket;
27 11 }
28 12
29   - public void send(String sendText) throws Exception {
30   - byte[] sendBytes = sendText.getBytes();
31   - serverSocket.send(new DatagramPacket(sendBytes, sendBytes.length, ip,
32   - serverPort));
  13 + public DatagramSocket getSocket() {
  14 + return socket;
33 15 }
34   -
35   - public String receive() throws Exception {
36   - byte[] receiceData = new byte[512];
37   - DatagramPacket datagramPacket = new DatagramPacket(receiceData,
38   - receiceData.length);
39   - clientSocket.receive(datagramPacket);
40   - return new String(datagramPacket.getData(), 0, datagramPacket
41   - .getLength());
  16 +
  17 + public void close() {
  18 + socket.close();
42 19 }
43 20 }
28 src/de/itagile/judp/JudpReceiver.java
... ... @@ -0,0 +1,28 @@
  1 +package de.itagile.judp;
  2 +
  3 +import java.io.IOException;
  4 +import java.net.DatagramPacket;
  5 +
  6 +public class JudpReceiver extends Judp {
  7 +
  8 + public JudpReceiver(int clientPort) {
  9 + super(DatagramSocketFactory.create(clientPort));
  10 + }
  11 +
  12 + public void setTimeout(int timeout) throws java.net.SocketException {
  13 + getSocket().setSoTimeout(timeout);
  14 + }
  15 +
  16 + public String receive() throws Exception {
  17 + return receive(512);
  18 + }
  19 +
  20 + public String receive(int packetSize) throws IOException {
  21 + byte[] receiceData = new byte[packetSize];
  22 + DatagramPacket datagramPacket = new DatagramPacket(receiceData,
  23 + receiceData.length);
  24 + getSocket().receive(datagramPacket);
  25 + return new String(datagramPacket.getData(), 0, datagramPacket
  26 + .getLength());
  27 + }
  28 +}
26 src/de/itagile/judp/JudpSender.java
... ... @@ -0,0 +1,26 @@
  1 +package de.itagile.judp;
  2 +
  3 +import java.net.DatagramPacket;
  4 +import java.net.InetAddress;
  5 +
  6 +public class JudpSender extends Judp {
  7 + private InetAddress addressSendTo;
  8 + private int serverPort;
  9 +
  10 + public JudpSender(String ip, int serverPort) {
  11 + super(DatagramSocketFactory.create());
  12 + this.serverPort = serverPort;
  13 + try {
  14 + this.addressSendTo = InetAddress.getByName(ip);
  15 + } catch (java.net.UnknownHostException e) {
  16 + throw new UnknownHostException(e);
  17 + }
  18 + }
  19 +
  20 + public void send(String sendText) throws Exception {
  21 + byte[] sendBytes = sendText.getBytes();
  22 + getSocket().send(
  23 + new DatagramPacket(sendBytes, sendBytes.length, addressSendTo,
  24 + serverPort));
  25 + }
  26 +}
10 src/de/itagile/judp/SocketException.java
... ... @@ -0,0 +1,10 @@
  1 +package de.itagile.judp;
  2 +
  3 +public class SocketException extends RuntimeException {
  4 +
  5 + private static final long serialVersionUID = 1L;
  6 +
  7 + public SocketException(java.net.SocketException e) {
  8 + super(e);
  9 + }
  10 +}
10 src/de/itagile/judp/UnknownHostException.java
... ... @@ -0,0 +1,10 @@
  1 +package de.itagile.judp;
  2 +
  3 +public class UnknownHostException extends RuntimeException {
  4 +
  5 + private static final long serialVersionUID = 1L;
  6 +
  7 + public UnknownHostException(java.net.UnknownHostException e) {
  8 + super(e);
  9 + }
  10 +}
35 test/de/itagile/judp/IntegrationTest.java
... ... @@ -0,0 +1,35 @@
  1 +package de.itagile.judp;
  2 +
  3 +import static org.junit.Assert.assertEquals;
  4 +import static org.junit.Assert.assertFalse;
  5 +
  6 +import org.junit.After;
  7 +import org.junit.Test;
  8 +
  9 +public class IntegrationTest {
  10 +
  11 + private static final int PORT = 8123;
  12 + private static final String EXPECTED = "expected";
  13 + private final JudpReceiver receiver = new JudpReceiver(PORT);
  14 + private final JudpSender sender = new JudpSender("127.0.0.1", PORT);
  15 +
  16 + @Test
  17 + public void receivesWithDefaultPacketSize() throws Exception {
  18 + sender.send(EXPECTED);
  19 +
  20 + assertEquals(EXPECTED, receiver.receive());
  21 + }
  22 +
  23 + @Test
  24 + public void receivesNotFullStringWhenPacketSizeTooSmall() throws Exception {
  25 + sender.send(EXPECTED);
  26 +
  27 + assertFalse(EXPECTED.equals(receiver.receive(2)));
  28 + }
  29 +
  30 + @After
  31 + public void closeSockets() {
  32 + receiver.close();
  33 + sender.close();
  34 + }
  35 +}

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.