- Overview
- Network Programming with J2SE Versus J2ME
- The Generic Connection Framework
- Wireless Network Programming Using Sockets
- Wireless Network Programming Using Datagrams
- Wireless Network Programming Using HttpConnection
- Summary
Wireless Network Programming Using Sockets
A socket is one end-point of a two-way communication link between programs running on the network. A socket connection is the most basic low-level reliable communication mechanism between a wireless device and a remote server or between two wireless devices. The socket communication capability provided with some of the mobile devices in J2ME enables a variety of client/server applications. Using the socket connection to SMTP and POP3 servers, an e-mail client on wireless devices can send or receive regular Internet e-mail messages.
Socket use gives J2ME developers the flexibility to develop all kinds of network applications for wireless devices. However, not every wireless manufacturer supports socket communication in MIDP devices, which means that wireless applications developed using sockets could be limited to certain wireless devices and are less likely to be portable across different types of wireless networks.
To use a socket, the sender and receiver that are communicating must first establish a connection between their sockets. One will be listening for a request for a connection, and the other will be asking for a connection. Once two sockets have been connected, they may be used for transmitting data in either direction.
To receive data from the remote server, InputConnection has to be established and an InputStream must be obtained from the connection. To send data to the remote server, OutputConnection has to be established and an OutputStream must be obtained from the connection. In J2ME, three types of connections are defined to handle input/output streams: InputConnection, OutputConnection, and StreamConnection. As the names indicate, InputConnection defines the capabilities for input streams to receive data and OutputConnection defines the capabilities for output streams to send data. StreamConnection defines the capabilities for both input and output streams. When to use which connection depends on whether the data needs to be sent, received, or both.
Network programming using sockets is very straightforward in J2ME. The process works as follows:
A socket connection is opened with a remote server or another wireless device using Connector.open().
InputStream or OutputStream is created from the socket connection for sending or receiving data packets.
Data can be sent to and received from the remote server via the socket connection by performing read or write operations on the InputStream or OutputStream object.
The socket connection and input or output streams must be closed before exiting the program.
The example in Listing 9.2 demonstrates how a socket connection is created and how a DataOutputStream is opened on top of the connection.
Listing 9.2 Listing2.txt
/** * This sample code block demonstrates how to open a * socket connection, how to establish a DataOutputStream * from this socket connection, and how to free them up * after use. **/ // include the networking class libraries import javax.microedition.io.*; // include the I/O class libraries import java.io.*; // more code here ... // define the connect string with protocol: socket, // hostname: 64.28.105.110, and port number: 80 String connectString = "socket://64.28.105.110:80"; OutputConnection sc = null; DataOutputStream dos = null; // IOException must be caught when Connector.open() is called. try { // a socket connection is established with the remote server. sc = (OutputConnection) Connector.open(socketUrlString); // an OutputStream is created on top of the OutputConnection // object for write operations. dos = sc.openDataOutputStream(); // perform write operations that send data to the remote server ... } catch (IOException e) { System.err.println("IOException caught:" + e) } finally { // free up the I/O stream after use try { if (dos != null ) dos.close(); } catch (IOException ignored) {} // free up the socket connection after use try { if ( sc != null ) sc.close(); } catch (IOException ignored) {} } // more code here ...
In this example, a socket connection is established with remote server 64.28.105.110 on port 80. Port 80 is the well-known port for HTTP service. Note that we are using the socket connection to communicate with the remote server; therefore, the protocol is specified as socket. The DataOutputStream is then created on the top of the connection for sending requests to the remote server.
Sample Program
The sample program in Listing 9.3 creates a Web client session to request a page from a Web server on the Internet. Figure 9.3 illustrates the program flow of a Web client implemented using socket connections.
Figure 9.3 The program flow of a Web client implemented with sockets.
Listing 9.3 SocketExample.java
/** * The following MIDlet application creates socket connection with * a remote Web server at port 80, and then sends an HTTP request * to retrieve the Web page "index.html" via the connection. */ // include MIDlet class libraries import javax.microedition.midlet.*; // include networking class libraries import javax.microedition.io.*; // include GUI class libraries import javax.microedition.lcdui.*; // include I/O class libraries import java.io.*; public class SocketExample extends MIDlet { // StreamConnection allows bidirectional communication private StreamConnection streamConnection = null; // use OutputStream to send requests private OutputStream outputStream = null; private DataOutputStream dataOutputStream = null; // use InputStream to receive responses from Web server private InputStream inputStream = null; private DataInputStream dataInputStream = null; // specify the connect string private String connectString = "socket://64.28.105.110:80"; // use a StrignBuffer to store the retrieved page contents private StringBuffer results; // define GUI components private Display myDisplay = null; private Form resultScreen; private StringItem resultField; public SocketExample() { // initializing GUI display results = new StringBuffer(); myDisplay = Display.getDisplay(this); resultScreen = new Form("Page Content:"); } public void startApp() { try { // establish a socket connection with remote server streamConnection = (StreamConnection) Connector.open(connectString); // create DataOuputStream on top of the socket connection outputStream = streamConnection.openOutputStream(); dataOutputStream = new DataOutputStream(outputStream); // send the HTTP request dataOutputStream.writeChars("GET /index.html \n"); dataOutputStream.flush(); // create DataInputStream on top of the socket connection inputStream = streamConnection.openInputStream(); dataInputStream = new DataInputStream(inputStream); // retrieve the contents of the requested page from Web server int inputChar; while ( (inputChar = dataInputStream.read()) != -1) { results.append((char) inputChar); } // display the page contents on the phone screen resultField = new StringItem(null, results.toString()); resultScreen.append(resultField); myDisplay.setCurrent(resultScreen); } catch (IOException e) { System.err.println("Exception caught:" + e); } finally { // free up I/O streams and close the socket connection try { if (dataInputStream != null) dataInputStream.close(); } catch (Exception ignored) {} try { if (dataOutputStream != null) dataOutputStream.close(); } catch (Exception ignored) {} try { if (outputStream != null) outputStream.close(); } catch (Exception ignored) {} try { if (inputStream != null) inputStream.close(); } catch (Exception ignored) {} try { if (streamConnection != null) streamConnection.close(); } catch (Exception ignored) {} } } public void pauseApp() { } public void destroyApp(boolean unconditional) { } }
The program first opens a socket connection with the Web server http://www.webyu.com at port 80. It sends an HTTP request to the Web server using the DataOutputStream established from the connection. It receives the requested content from the Web server using the DataInputStream opened from the connection. After the Web page content is completely received, the content is displayed on the emulator.
Because the program needs to perform bidirectional communication between a cell phone and a Web server, StreamConnection is used to support both the send and receive operations.
Figure 9.4 illustrates a screen shot of the Web page content displayed on the Motorola iDEN 3000 Emulator.
Figure 9.4 A screenshot of SocketExample.java.
So far, we have talked about how to develop wireless applications using sockets. The previous example used a socket connection to communicate with a Web server to retrieve a Web document. The next section examines how to develop J2ME applications using datagram connections to communicate with a remote server or another wireless device. This datagram communication is based on the UDP protocol.