Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Separation of concerns and simpler API #2

Merged
merged 4 commits into from

3 participants

@lomin

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();
     }
}
@UrsKR

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.

@nbotzet nbotzet merged commit 9a05f93 into nbotzet:master
@nbotzet
Owner
@UrsKR

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
Commits on Sep 22, 2011
  1. @lomin
  2. @lomin

    Edited README.md via GitHub

    lomin authored
  3. @lomin

    updated .gitignore

    lomin authored
  4. @lomin

    updated .gitignore

    lomin authored
This page is out of date. Refresh to see the latest.
View
8 .classpath
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="src" path="test"/>
+ <classpathentry kind="output" path="bin"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER" exported="true"/>
+ <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"/>
+</classpath>
View
5 .gitignore
@@ -0,0 +1,5 @@
+*.class
+bin
+build
+.settings
+.gradle
View
17 .project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <links/>
+ <name>judp</name>
+ <comment/>
+ <projects/>
+ <natures>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments/>
+ </buildCommand>
+ </buildSpec>
+ <linkedResources/>
+</projectDescription>
View
56 README.md
@@ -4,28 +4,34 @@ Java UDP
This library provides a helpful abstraction over Java's built in UDP handling.
-Usage
---------
-
-Create a
-
- JUDP judp = new JUDP();
-
-and initialize it with
-
- judp.start(inetAdress, serverport, clientport);
-
-where inetAdress is the IP adress of the server you want to talk to,
-serverport is the port you wand to send to,
-and clientport is the port you want to listen on.
-
-Use
-
- judp.receive()
-
-to get an incoming package (best used in a running loop)
-and
-
- judp.send(message)
-
-to send the String "message" to the server.
+See the IntegrationTest for Usage:
+<pre>
+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();
+ }
+}
+</pre>
View
30 build.gradle
@@ -0,0 +1,30 @@
+apply plugin: 'java'
+apply plugin: 'eclipse'
+
+sourceCompatibility=1.6
+targetCompatibility=1.6
+
+version='1.0.0'
+
+defaultTasks 'clean', 'build'
+
+repositories {
+ mavenCentral()
+}
+
+dependencies {
+ testCompile group: 'junit', name: 'junit', version: '4.7'
+}
+
+sourceSets {
+ main {
+ java {
+ srcDir 'src'
+ }
+ }
+ test {
+ java {
+ srcDir 'test'
+ }
+ }
+}
View
BIN  judp.jar
Binary file not shown
View
22 src/de/itagile/judp/DatagramSocketFactory.java
@@ -0,0 +1,22 @@
+package de.itagile.judp;
+
+import java.net.DatagramSocket;
+
+public class DatagramSocketFactory {
+
+ public static DatagramSocket create() {
+ try {
+ return new DatagramSocket();
+ } catch (java.net.SocketException e) {
+ throw new SocketException(e);
+ }
+ }
+
+ public static DatagramSocket create(int port) {
+ try {
+ return new DatagramSocket(port);
+ } catch (java.net.SocketException e) {
+ throw new SocketException(e);
+ }
+ }
+}
View
39 src/de/itagile/judp/Judp.java
@@ -1,43 +1,20 @@
package de.itagile.judp;
-import java.net.DatagramPacket;
import java.net.DatagramSocket;
-import java.net.InetAddress;
public class Judp {
- private InetAddress ip;
- private int serverPort;
- private DatagramSocket serverSocket;
- private DatagramSocket clientSocket;
- public static void main(String[] args) throws Exception {
- Judp updServer = new Judp();
- updServer.start(InetAddress.getByName(args[0]), (int) new Integer(
- args[1]), (int) new Integer(args[2]));
- System.out.println(updServer.receive());
- }
+ private final DatagramSocket socket;
- public void start(InetAddress ip, int serverPort, int clientPort)
- throws Exception {
- this.ip = ip;
- this.serverPort = serverPort;
- serverSocket = new DatagramSocket();
- clientSocket = new DatagramSocket(clientPort);
- clientSocket.setSoTimeout(2000);
+ public Judp(DatagramSocket socket) {
+ this.socket = socket;
}
- public void send(String sendText) throws Exception {
- byte[] sendBytes = sendText.getBytes();
- serverSocket.send(new DatagramPacket(sendBytes, sendBytes.length, ip,
- serverPort));
+ public DatagramSocket getSocket() {
+ return socket;
}
-
- public String receive() throws Exception {
- byte[] receiceData = new byte[512];
- DatagramPacket datagramPacket = new DatagramPacket(receiceData,
- receiceData.length);
- clientSocket.receive(datagramPacket);
- return new String(datagramPacket.getData(), 0, datagramPacket
- .getLength());
+
+ public void close() {
+ socket.close();
}
}
View
28 src/de/itagile/judp/JudpReceiver.java
@@ -0,0 +1,28 @@
+package de.itagile.judp;
+
+import java.io.IOException;
+import java.net.DatagramPacket;
+
+public class JudpReceiver extends Judp {
+
+ public JudpReceiver(int clientPort) {
+ super(DatagramSocketFactory.create(clientPort));
+ }
+
+ public void setTimeout(int timeout) throws java.net.SocketException {
+ getSocket().setSoTimeout(timeout);
+ }
+
+ public String receive() throws Exception {
+ return receive(512);
+ }
+
+ public String receive(int packetSize) throws IOException {
+ byte[] receiceData = new byte[packetSize];
+ DatagramPacket datagramPacket = new DatagramPacket(receiceData,
+ receiceData.length);
+ getSocket().receive(datagramPacket);
+ return new String(datagramPacket.getData(), 0, datagramPacket
+ .getLength());
+ }
+}
View
26 src/de/itagile/judp/JudpSender.java
@@ -0,0 +1,26 @@
+package de.itagile.judp;
+
+import java.net.DatagramPacket;
+import java.net.InetAddress;
+
+public class JudpSender extends Judp {
+ private InetAddress addressSendTo;
+ private int serverPort;
+
+ public JudpSender(String ip, int serverPort) {
+ super(DatagramSocketFactory.create());
+ this.serverPort = serverPort;
+ try {
+ this.addressSendTo = InetAddress.getByName(ip);
+ } catch (java.net.UnknownHostException e) {
+ throw new UnknownHostException(e);
+ }
+ }
+
+ public void send(String sendText) throws Exception {
+ byte[] sendBytes = sendText.getBytes();
+ getSocket().send(
+ new DatagramPacket(sendBytes, sendBytes.length, addressSendTo,
+ serverPort));
+ }
+}
View
10 src/de/itagile/judp/SocketException.java
@@ -0,0 +1,10 @@
+package de.itagile.judp;
+
+public class SocketException extends RuntimeException {
+
+ private static final long serialVersionUID = 1L;
+
+ public SocketException(java.net.SocketException e) {
+ super(e);
+ }
+}
View
10 src/de/itagile/judp/UnknownHostException.java
@@ -0,0 +1,10 @@
+package de.itagile.judp;
+
+public class UnknownHostException extends RuntimeException {
+
+ private static final long serialVersionUID = 1L;
+
+ public UnknownHostException(java.net.UnknownHostException e) {
+ super(e);
+ }
+}
View
35 test/de/itagile/judp/IntegrationTest.java
@@ -0,0 +1,35 @@
+package de.itagile.judp;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+
+import org.junit.After;
+import org.junit.Test;
+
+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();
+ }
+}
Something went wrong with that request. Please try again.