A note on XMPP communications protocol

    When it comes to messaging, I’ve been interested to know how messaging protocols work such as XMPP (Extensible Messaging and Presence Protocol) communications protocol, which is an open standard for messaging that provides a set of protocols for message exchange based on XML. Applications such as WhatsApp, GoogleTalk and Facebook external chat API to name a few, uses the XMPP protocol (or a customized version of the protocol). While the standards are open, these protocols themselves are complicated and heavyweight with a lot of overhead because of the extensive use of XML. Some application servers such as Ejabberd, Openfire, Tigase, Prosody have implemented these protocols for messaging. Based on the protocols (XEPs) implemented by these XMPP servers, client software/ IM applications can use these protocols for connecting with the servers. You can compare the list of messaging protocols here. When choosing a protocol, many factors come into play. But since more of the messaging happens in real-time, we want to minimize overhead and maintain a steady connection. Scalability, concurrency and reliability plays important roles. Due to this, some of the applications such as GTalk has moved on and replaced by Google Hangouts which uses its own protocols for messaging. However, it is interesting to learn how these protocols work providing insights in handling messages, presence, roster, group sharing, etc. We also have a list of client software and libraries which we can use to connect to the XMPP server. In the next series of posts, I will walk through setting up your own XMPP (Jabber) server and use libraries such as Smack API a Java library for both Android and Java backend and JavaScript libraries such as Strophejs for connecting to your Jabber server. Personally I’ve never used Tigase or Prosody, but when it comes to performance I highly recommend using Ejabberd.

Advertisements

Java Socket Programming – Part II

In the second part, we need to have a server component that listens to client connections. This is a very basic demonstration of how clients connect to servers in the client-server architecture. In real world applications, we need to implement threads that listens to connections. Here is the code for the server side that runs in a single thread. We need to start the server component first so that it can receive client connections. If you change the port number, make sure you use the same port number for both modules.

/**
 * Socket programming  using  Java
 * Server component
 */

import java.io.*;
import java.net.*;
import java.util.*;

public class ServerDemo {
  public static void main( String args[] ) throws IOException {

    // open a port for connection
    short portnumber = 7777;   // assuming your own port
    int byteSize = 0, bufferSize = 0, filesize = 1048576; //max size - 1Mb

    FileInputStream fin = null;

    // define the server object
    ServerSocket serverSocket = null;
    try {
      serverSocket = new ServerSocket( portnumber );
      System.out.println("Waiting...");
      serverSocket.setSoTimeout(20000);   // set connection timeout
    } catch ( IOException e ) {
      System.exit(1);
    }

    // define client socket object
    Socket clientSocket = null;
    try {
      clientSocket = serverSocket.accept();
    } catch (SocketTimeoutException e) {
      System.out.println("Connection timed out!");
      System.exit(1);
    } catch ( IOException e ) {
      System.out.println("I/O error " + e);
      System.exit(1);
    }

    if (serverSocket != null ) {
      System.out.println("Connected to " + clientSocket.getInetAddress() + " on port "
        + clientSocket.getPort() + ", local port  " + clientSocket.getLocalPort());
      System.out.println("Waiting for request from " + clientSocket. getInetAddress());

      //create a new file to store incoming bytes
      byte [] buffer = null;
      InputStream in = null;
      String newfile = null;
      try {
        buffer  = new byte [filesize];
        in = clientSocket.getInputStream();
      } catch ( Exception e ) {
        System.out.println(e.getMessage());
      }      

      //open file stream for writing the contents of the file
      FileOutputStream fout = null;
      BufferedOutputStream bos = null;
      try{
        fout = new FileOutputStream("_temp~1.txt");
        byteSize = in.read( buffer, 0, buffer.length );
        bufferSize = byteSize;
      } catch ( Exception e ) {
        System.out.println(e.getMessage());
      }
      do {
        try {
          byteSize = in.read(buffer, bufferSize, ( buffer.length-bufferSize ));
          if(byteSize >= 0) {
            bufferSize += byteSize;
          }
        } catch (Exception e) {
          System.out.println("Error: Cannot receive file!");
          System.exit(1);
        }
      } while(byteSize > -1);

      try {
        bos = new BufferedOutputStream(fout);
        bos.write(buffer, 0, bufferSize);
        bos.flush();
        System.out.println("File received from " + clientSocket.getInetAddress());
        bos.close();
        fin = new FileInputStream("_temp~1.txt");

        //prompt for reading file
        String userInput = null;
        BufferedReader input = new BufferedReader( new InputStreamReader( System.in ));
        System.out.print("Do you want to display the contents of the file ? [y/n] : ");
        userInput = input.readLine();
        int i;
        if (userInput.equalsIgnoreCase("y")) {
          System.out.println();
          do {
            i = fin.read();
            if(i != -1) System.out.print((char) i);
          } while(i != -1); // read until end of file
        }
        in.close();
        fin.close();

        //prompt for saving file
        System.out.print("Do you want to save the file ? [y/n] : ");
        userInput = input.readLine();
        File f = null;
        f = new File("_temp~1.txt");
        if (userInput.equalsIgnoreCase("y")) {
          BufferedReader fileBr = new BufferedReader( new InputStreamReader ( System.in ));
          System.out.print("Specify a filename: ");
          newfile = fileBr.readLine();
          Boolean b = f.renameTo(new File(newfile));
          if( b )
            System.out.println("File successfully saved as \"" + newfile + "\"");
          else
            System.out.println("An error occured while saving file!");
        } else
          f.delete();
        in.close();
      } catch ( Exception e ) {
        System.out.println("Error : Could not save file!");
      } finally {
        serverSocket.close();
      }
    }
  }
}

 

Java Socket Programming – Part 1

Here is a simple socket programming which allows a client to be connected to a server using Java. Lets create a simple file transfer from a client machine to the server.

  1. First make a connection with the server
  2. If the connection was successful, open a text file (in the client’s machine)
  3. Send the file to the server

The following code will be used for client

/**
 * Socket programming  using  Java
 * A client to server connection
 */

import java.io.*;
import java.net.*;

public class ClientDemo {
  public static void main( String args[] ) throws IOException {

    // open a port for connection
    short portnumber = 7777; // assuming your own port
    String hostname, fileName;
    OutputStream os = null;

    // get hostname or ip address of the server
    BufferedReader host = new BufferedReader( new InputStreamReader ( System.in ));
    System.out.print("Enter the server name: ");
    hostname = host.readLine();

    // define client socket object
    Socket clientSocket = null;
    try {
      clientSocket = new Socket( hostname, portnumber );
      System.out.println("Connecting to " + hostname + " on port " + portnumber + "...");
    } catch ( UnknownHostException e ) {
      System.out.println("Unknown server : " + e.getMessage());
      System.exit(1);
    } catch ( IOException e ) {
      System.out.println(e.getMessage());
    }

    // send file to server
    if (clientSocket != null ) {
      System.out.println("Connection accepted");
      BufferedReader fileBr = new BufferedReader( new InputStreamReader ( System.in ));

      // open file for transfer
      System.out.print("Enter the name of the text file you want to sent: ");
      fileName = fileBr.readLine();
      File myTextFile = new File (fileName);

      // open file stream for sending bytes of data
      byte [] buffer  = new byte [(int)myTextFile.length()];
      try {
        FileInputStream fin = new FileInputStream(myTextFile);
        BufferedInputStream bin = new BufferedInputStream(fin);
        bin.read( buffer, 0, buffer.length);
        os = clientSocket.getOutputStream();
        System.out.println("Sending...");
        os.write(buffer, 0, buffer.length);
        os.flush();
        System.out.println("File was send sucessfully!");
      } catch ( IOException e ) {
        System.out.println("File not found!");
      } finally {
        clientSocket.close();
      }
    } else {
      System.out.println("Connection failed!");
      System.exit(1);
    }
  }
}

Welcome

Welcome to my personal blog. I like to share my thoughts and experiences in varied topics ranging from programming, music, life, poetry, nature, etc. If you find something useful, share the love and spread the word. Cheers!