Channels ▼
RSS

C/C++

Java and C++ Socket Communication


The Java Client

The sample Java client is written as a Java Swing application, which includes a user interface with buttons to make requests, and a list view to display the server responses (see Figure 2). There's also a button labeled Connect, and when pressed, the client attempts to connect to the server at the supplied address. The address defaults to localhost, but you can change this to any valid hostname or IP address. As a result, you have the choice to run both the client and server applications on one computer, or on separate computers, without issue. We'll examine the sample C++ server application later.


Figure 2: The sample Java client application user interface.

The heart of the application is the Java network and IO code, which is encapsulated inside one class, SocketClient, shown partially in Example 3. This class contains two embedded classes called Listener and Sender, which listen for requests and send responses, respectively.


public class SocketClient {
    private Listener listener = null; // listens for requests
    private Sender sender = null;     // sends responses
    public boolean connected = false;
    ServerResponses viewer = null;

    class Listener extends Thread {
        // ...
    }

    class Sender {
        static final String HOSTNAME = ...
        static final String MEMORY = ...
        static final String RANDOM_NUM = ... 
        // ...
    }

    public SocketClient(String IPAddress, 
                       ServerResponses viewer) {
            // ...
    }

    public boolean isConnected() {
        return connected;
    }

    public void requestHostname() {
        sender.requestHostname();
    }

    public void requestMemory() {
        sender.requestMemory();
    }

    public void requestRandomNumber() {
        sender.requestRandomNumber();
    }
}

Example 3:The SocketClient class implements all of the code to send requests and listen for server responses.

A connection to the server is established when a SocketClient object is created. The first parameter of the constructor is the address of the server to connect to, and the second parameter is a reference to an object that implements the ServerResponses interface, shown in Example 4.


public interface ServerResponses {
    public void onHostnameResponse(String msg);
    public void onMemoryResponse(String msg);
    public void onRandomNumberResponse(String msg);
}

Example 4: The ServerResponses interface methods are called as response messages arrive.

As a result, the user interface code drives the connection and request process by instantiating the SocketClient class when the Connect button is pressed, and later calling any of its public methods — requestHostname(), requestMemory(), and requestRandomNumber() — when the associated button is pressed. When a response is received from a prior request, the appropriate method is called on the ServerResponses reference provided.

In this sample Java client, each time you press one of the request buttons, a request message is sent to the server, and the associated response message text is displayed at the top of the list view (see Figure 3).

Figure 3: The Java client displaying some server responses

Here, you also see that the display has been updated to show a connection to the server at address 192.168.0.180. Let's examine the Java network communication code in more detail.

Java Network Programming

When the SocketClient class is created (Listing One, the complete implementation, and related files are available here.

The code in the constructor attempts to connect to a server at the given IP address on port 8080. This code looks similar to the following:


try {
    java.net.Socket socket = 
        new java.net.Socket("localhost", 8080);
    this.listener = new Listener(socket);
    this.sender =  new Sender(socket);
}
catch ( Exception e ) {
    e.printStackTrace();
}

The code is simple:

  • If the connection attempt fails, an Exception is thrown
  • If the connection attempt succeeds, the active socket is passed to the Listener and Sender classes to perform the real work.

To send a network message using this active socket, you need to use Java IO streams, which are part of the java.io package. The Sender class encapsulates this implementation, but in summary, to send a network message you need to begin with the socket's output stream, which is used to send data. For efficiency, we wrap this stream in a java.io.BufferedOutputStream object, and then write the message's bytes to this stream:


String xml = "<Request><Name>GetHostname</Name></Request>";
BufferedOutputStream bos = 
    new BufferedOutputStrean( socket.getOutputStream() );
bos.write( xml.getBytes() ); // writes to the buffer
bos.flush() ; // writes the buffer to the network

The code to listen for network messages is similar in that it also uses Java IO streams. However, due to the nature of waiting for a message, you typically perform this task in a separate thread. The Listener class extends class Thread, and makes its call to one of the blocking read() methods in the Thread.run() method when started.

Executing this code in a separate thread ensures that the rest of application is able to execute (and respond to user input, for instance) while the blocking read() method waits for data for an unpredictable length of time. This solution is simple and elegant enough for this application, but for applications that need to communicate over many socket connections, creating a thread per socket may not scale well. Alternatively you can specify a timeout on the read() method and call it periodically (polling), or perform non-blocking IO (beyond the scope of this article) in those situations.

The code in the Listener class that performs this task is similar to the following:


public void run() {
    // Create a reader to wrap the socket's InputStream
    InputStreamReader inputReader = 
        new InputStreamReader(socket.getInputStream() );
    BufferedReader bufferedReader = 
        new BufferedReader( inputReader );
    while ( true ) {
        // readLine blocks until a message arrives
        String xml = reader.readLine(); 
        // process the XML ...
    }
}

As stated earlier, the Java Swing code controls the sending of request messages as the user clicks on the appropriate buttons, and subsequently displays the server response messages in a list view. Listing Two, which contains this implementation and the complete Java client application and related files are available here.


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.
 

Video