1   /*
2    *  MicroEmulator
3    *  Copyright (C) 2007 Ludovic Dewailly <ludovic.dewailly@dreameffect.org>
4    *
5    *  It is licensed under the following two licenses as alternatives:
6    *    1. GNU Lesser General Public License (the "LGPL") version 2.1 or any newer version
7    *    2. Apache License (the "AL") Version 2.0
8    *
9    *  You may not use this file except in compliance with at least one of
10   *  the above two licenses.
11   *
12   *  You may obtain a copy of the LGPL at
13   *      http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt
14   *
15   *  You may obtain a copy of the AL at
16   *      http://www.apache.org/licenses/LICENSE-2.0
17   *
18   *  Unless required by applicable law or agreed to in writing, software
19   *  distributed under the License is distributed on an "AS IS" BASIS,
20   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21   *  See the LGPL or the AL for the specific language governing permissions and
22   *  limitations.
23   */
24  
25  package org.microemu.cldc.datagram;
26  
27  import java.io.IOException;
28  import java.net.DatagramPacket;
29  import java.net.DatagramSocket;
30  import java.net.InetAddress;
31  
32  import javax.microedition.io.Connector;
33  import javax.microedition.io.Datagram;
34  import javax.microedition.io.UDPDatagramConnection;
35  
36  import junit.framework.TestCase;
37  
38  /**
39   * Test end to end communication over datagram.
40   */
41  public class EndToEndDatagramTest extends TestCase {
42  
43  	private static final String MESSAGE = "Hello World!";
44  
45  	private static final String HOST = "localhost";
46  
47  	private static final int PORT = 1234;
48  
49  	private static final int COUNT = 10;
50  
51  	private static final String UTF8 = "UTF-8";
52  
53  	private static final int BUFFER_SIZE = 1024;
54  
55  	/**
56  	 * Tests connection from J2SE datagram socket to J2ME datagram connection
57  	 */
58  	public void testJ2SEtoJ2ME() throws Exception {
59  		System.out.println("\n--------------------------------------------\n");
60  		createJ2SEServer().start();
61  		Thread.sleep(100);
62  		Thread clientThread = createJ2MEClient(false);
63  		clientThread.start();
64  		// wait for client thread to complete
65  		clientThread.join();
66  		System.out.println("\n--------------------------------------------\n");
67  	}
68  
69  	/**
70  	 * Tests connection from J2ME datagram connection to J2SE datagram socket
71  	 */
72  	public void testJ2MEtoJ2SE() throws Exception {
73  		System.out.println("\n--------------------------------------------\n");
74  		createJ2MEServer(false).start();
75  		Thread.sleep(100);
76  		Thread clientThread = createJ2SEClient();
77  		clientThread.start();
78  		// wait for client thread to complete
79  		clientThread.join();
80  		System.out.println("\n--------------------------------------------\n");
81  	}
82  
83  	/**
84  	 * Tests connection from J2ME datagram connection to J2ME datagram
85  	 * connection
86  	 */
87  	public void testJ2MEtoJ2ME() throws Exception {
88  		System.out.println("\n--------------------------------------------\n");
89  		createJ2MEServer(true).start();
90  		Thread.sleep(100);
91  		Thread clientThread = createJ2MEClient(true);
92  		clientThread.start();
93  		// wait for client thread to complete
94  		clientThread.join();
95  		System.out.println("\n--------------------------------------------\n");
96  	}
97  
98  	/**
99  	 * Tests connection from J2SE datagram socket to J2SE datagram socket
100 	 */
101 	public void testJ2SEtoJ2SE() throws Exception {
102 		System.out.println("\n--------------------------------------------\n");
103 		createJ2SEServer().start();
104 		Thread.sleep(100);
105 		Thread clientThread = createJ2SEClient();
106 		clientThread.start();
107 		// wait for client thread to complete
108 		clientThread.join();
109 		System.out.println("\n--------------------------------------------\n");
110 	}
111 
112 	private Thread createJ2MEServer(final boolean useDataStream) throws Exception {
113 		// create server connection
114 		final UDPDatagramConnection serverConn = (UDPDatagramConnection) Connector.open(Connection.PROTOCOL + ":"
115 				+ PORT, Connector.READ_WRITE);
116 		final int[] counter = { 0 };
117 		return new Thread(new Runnable() {
118 			public void run() {
119 				try {
120 					Datagram request = serverConn.newDatagram(BUFFER_SIZE);
121 					for (int i = 0; i < COUNT; i++) {
122 						request.reset();
123 						// wait for message to be received
124 						System.out.println("Server (J2ME): Waiting for request...");
125 						serverConn.receive(request);
126 						System.out.println("Server (J2ME): Request received from " + request.getAddress());
127 						// check its integrity
128 						if (useDataStream) {
129 							assertEquals(MESSAGE, request.readUTF());
130 						} else {
131 							assertEquals(MESSAGE, new String(request.getData(), 0, request.getLength(), UTF8));
132 						}
133 						// and respond
134 						Datagram response = serverConn.newDatagram(BUFFER_SIZE);
135 						if (useDataStream) {
136 							response.writeUTF(MESSAGE);
137 						} else {
138 							byte[] data = MESSAGE.getBytes(UTF8);
139 							response.setData(data, 0, data.length);
140 						}
141 						response.setAddress(request);
142 						serverConn.send(response);
143 						System.out.println("Server (J2ME): Datagram sent to " + response.getAddress());
144 						counter[0]++;
145 					}
146 					assertEquals(COUNT, counter[0]);
147 				} catch (Exception e) {
148 					fail("Error in server thread" + e.toString());
149 					e.printStackTrace();
150 				} finally {
151 					try {
152 						serverConn.close();
153 					} catch (IOException e) {
154 						fail("Unable to close server connection: " + e.toString());
155 					}
156 				}
157 			}
158 		}, "J2ME Server Thread");
159 	}
160 
161 	private Thread createJ2MEClient(final boolean useDataStream) throws Exception {
162 		// create client connection
163 		final UDPDatagramConnection clientConn = (UDPDatagramConnection) Connector.open(Connection.PROTOCOL + HOST
164 				+ ":" + PORT, Connector.READ_WRITE);
165 		final int[] counter = { 0 };
166 		return new Thread(new Runnable() {
167 			public void run() {
168 				try {
169 					Datagram request = clientConn.newDatagram(BUFFER_SIZE);
170 					for (int i = 0; i < COUNT; i++) {
171 						request.reset();
172 						// send the request to the server
173 						if (useDataStream) {
174 							request.writeUTF(MESSAGE);
175 						} else {
176 							byte[] data = MESSAGE.getBytes(UTF8);
177 							request.setData(data, 0, data.length);
178 						}
179 						clientConn.send(request);
180 						System.out.println("Client: Request sent to " + request.getAddress());
181 						// then wait for the response
182 						Datagram response = clientConn.newDatagram(BUFFER_SIZE);
183 						System.out.println("Client: Waiting for response...");
184 						clientConn.receive(response);
185 						System.out.println("Client: Response received from " + request.getAddress());
186 						if (useDataStream) {
187 							assertEquals(MESSAGE, response.readUTF());
188 						} else {
189 							assertEquals(MESSAGE, new String(response.getData(), 0, request.getLength(), UTF8));
190 						}
191 						counter[0]++;
192 					}
193 					assertEquals(COUNT, counter[0]);
194 				} catch (Exception e) {
195 					fail("Error in client thread" + e.toString());
196 					e.printStackTrace();
197 				} finally {
198 					try {
199 						clientConn.close();
200 					} catch (IOException e) {
201 						fail("Unable to close client connection: " + e.toString());
202 						e.printStackTrace();
203 					}
204 				}
205 			}
206 		}, "J2ME Client Thread");
207 	}
208 
209 	private Thread createJ2SEServer() throws Exception {
210 		// create server connection
211 		final DatagramSocket serverConn = new DatagramSocket(PORT);
212 		final int[] counter = { 0 };
213 		return new Thread(new Runnable() {
214 			public void run() {
215 				try {
216 					DatagramPacket request;
217 					for (int i = 0; i < COUNT; i++) {
218 						request = new DatagramPacket(new byte[BUFFER_SIZE], BUFFER_SIZE);
219 						// wait for message to be received
220 						System.out.println("Server (J2SE): Waiting for request...");
221 						serverConn.receive(request);
222 						System.out.println("Server (J2SE): Request received from " + request.getAddress() + ":"
223 								+ request.getPort());
224 						// check its integrity
225 						assertEquals(MESSAGE, new String(request.getData(), 0, request.getLength(), UTF8));
226 						// and respond
227 						DatagramPacket response = new DatagramPacket(new byte[BUFFER_SIZE], BUFFER_SIZE);
228 						byte[] data = MESSAGE.getBytes(UTF8);
229 						response.setData(data, 0, data.length);
230 						response.setAddress(request.getAddress());
231 						response.setPort(request.getPort());
232 						serverConn.send(response);
233 						System.out.println("Server (J2SE): Datagram sent to " + response.getAddress());
234 						counter[0]++;
235 					}
236 					assertEquals(COUNT, counter[0]);
237 				} catch (Exception e) {
238 					fail("Error in server thread" + e.toString());
239 					e.printStackTrace();
240 				} finally {
241 					serverConn.close();
242 				}
243 			}
244 		}, "J2SE Server Thread");
245 	}
246 
247 	private Thread createJ2SEClient() throws Exception {
248 		// create client connection
249 		final DatagramSocket clientConn = new DatagramSocket();
250 		clientConn.connect(InetAddress.getByName(HOST), PORT);
251 		final int[] counter = { 0 };
252 		return new Thread(new Runnable() {
253 			public void run() {
254 				try {
255 					DatagramPacket request;
256 					// wait for message to be received
257 					for (int i = 0; i < COUNT; i++) {
258 						byte[] data = MESSAGE.getBytes(UTF8);
259 						request = new DatagramPacket(data, data.length);
260 						request.setAddress(InetAddress.getByName(HOST));
261 						request.setPort(PORT);
262 						// send the request to the server
263 						clientConn.send(request);
264 						System.out.println("Client (J2SE): Request sent to " + request.getAddress() + ":"
265 								+ request.getPort());
266 						// then wait for the response
267 						DatagramPacket response = new DatagramPacket(new byte[BUFFER_SIZE], BUFFER_SIZE);
268 						System.out.println("Client (J2SE): Waiting for response...");
269 						clientConn.receive(response);
270 						System.out.println("Client (J2SE): Response received from " + request.getAddress() + ":"
271 								+ request.getPort());
272 						assertEquals(MESSAGE, new String(response.getData(), 0, response.getLength(), UTF8));
273 						counter[0]++;
274 					}
275 					assertEquals(COUNT, counter[0]);
276 				} catch (Exception e) {
277 					fail("Error in client thread" + e.toString());
278 					e.printStackTrace();
279 				} finally {
280 					clientConn.close();
281 				}
282 			}
283 		}, "J2SE Client Thread");
284 	}
285 }