Aegidius
 Plüss   Aplulogo
     
 www.aplu.ch      Print Text 
© 2021, V10.4
 
  TCPCom Module
 
Test Server/Client
 

 

Client and Server Test Arrangements

In general the development of client/server applications is not a trivial task, because the two programs are independent processes that interact by exchanging data and by state notifications. So the two systems are acting in parallel and multiprocessor/multithreading issues have to be applied. Because the human is not highly skilled to think in parallel, it is important to log the behavior of the the processes so it can be analyzed calmly afterwards. Because the program actions and the communication channel is often hidden by default, tools for spying what happens are of great importance. In short, during development and for debugging purposes, the system must be put in a "verbose" mode.

With TCPCom you can enter the verbose mode by setting the constructor parameter isVerbose of TCPServer and TCPClient to true. Moreover it is convenient to have a very simple server or client at hand to check the most fundamental behavior in the connecting or disconnecting phase or the sending and receiving of a single data block.

Because the Java and Python versions of TCPCom are identical, it is of no importance which version is used as test tool. So for example a server written in Java can easily tested with a test client written in Python. This may even be an advantage, because client/server applications are often developed on the same computer using a localhost connection and using different languages avoid possible interactions when programs run at the same time in the same IDE.

It is common to write verbose information to the System.out console, but this has some drawbacks because normally no user interaction other than killing the program is possible. To test the disconnection process, it is necessary to have a simple application windows with a few controls. In same cases a modal dialog will suffice, but to write out running process information a modeless dialog/console is necessary.

 

Java Test Server

For the test server/client in Java a convenient console window rom the ch.aplu.util package is used that redirects System.out information transparently to a text area (download here). Do not forget that the server should be smoothly shut down by calling its terminate() method in order to release the IP port, but the port is also freed when the Java virtual machine terminates.

import ch.aplu.tcpcom.*;
import ch.aplu.util.*;

public class TestServer implements TCPServerListener
{
  private TCPServer server;
  private Console c;

  public TestServer()
  {
    c = new Console();
    c.setTitle("Test Server");
    System.out.println("Server running. Close to stop.");
    int port = 5000;
    server = new TCPServer(port, true);
    server.addTCPServerListener(this);
    while (!c.isDisposed())
      Thread.yield();
    server.terminate();
  }

  public void onStateChanged(String state, String msg)
  {
    System.out.println(state + " - " + msg);
  }

  public static void main(String[] args)
  {
    new TestServer();
  }
}

Execute the program locally using WebStart

 

Java Test Client

Verbose output is also displayed in a console window from the ch.aplu.util package. Be aware that the console must be ready before the onStateChanged() callback is enabled by registering the TCPClientListener because the console is used by the callback.

import ch.aplu.tcpcom.*;
import ch.aplu.util.*;

public class TestClient implements TCPClientListener
{
  private TCPClient client;
  private Console c;

  public TestClient()
  {
    c = new Console();
    c.setTitle("Test Client");
    System.out.println("Trying to connect..");
    String host = "localhost";
    int port = 5000;
    client = new TCPClient(host, port, true);
    client.addTCPClientListener(this);
    boolean success = client.connect();
    if (success)
    {
      System.out.println("Connection successful. Close to disconnect");
//      client.sendMessage("Test Client says hello to you!");
      while (!c.isDisposed())
        Thread.yield();
      client.disconnect();
    }
    else
      System.out.println("Connection failed");
  }

  public void onStateChanged(String state, String msg)
  {
    System.out.println(state + " - " + msg);
  }

  public static void main(String[] args)
  {
    new TestClient();
  }
}

Execute the program locally using WebStart

 

Python Test Server

In Python modeless dialogs are not easily available, so the verbose output is simply written with print to the standard console. To terminate the server smoothly by hand, the main program hangs in a modal message dialog. With the TigerJython IDE the built-in function msgDlg() is used, in standard Python the dialog box is created with the easygui module (download here).

from tcpcom import TCPServer
# from easygui import msgbox  # Standard Python with easygui

def onStateChanged(state, msg):
    print state, "-", msg

port = 5000
server = TCPServer(port, stateChanged = onStateChanged, isVerbose = True)             
msgDlg("OK to terminate")  # TigerJython
# msgbox("Server running. OK to stop", "Test Server")  # Standard Python
server.terminate()

 

Python Test Client

Again the verbose output is written to the console and a modeless message dialog is used to display the connection information. Keep in mind that the connect() function is blocking until the connection is established or a timeout occurs. This happens when the server is not available because the IP address/port is incorrect or the server is not started. If another client is already handled by the server, connect() fails too and the callback reports SERVER_OCCUPIED.

from tcpcom import TCPClient
# from easygui import msgbox  # Standard Python with easygui

def onStateChanged(state, msg):
    print state, "-", msg

host = "localhost"
port = 5000

client = TCPClient(host, port, stateChanged = onStateChanged, isVerbose = True)
success = client.connect()
if success:
    msgDlg("OK to terminate")  # TigerJython
#    msgbox("Client connected. OK to disconnect","Test Client")  # Standard Python
    client.disconnect()
else:
    msgDlg("OK to terminate")  # TigerJython
#    msgbox("Client connection failed. OK to quit","Test Client")   # Standard Python