Monday 30 January 2017

Network (Socket) programming using java

Network (Socket) programming using java
Java is a premier tool for connecting computers over internet. It is very easy to write networking related programs in java language.
Connecting to server
All operating systems like Windows, UNIX, Linux supports a network debagging tool named telex. Telnet is generally preinstalled in the almost all the systems because it comes with operating systems. It can be launched by typing telnet in the command shell. In windows vista it is installed but it is by default inactive. To activate telnet in windows go to control panel, select programs, click “Turn Windows Features On or Off” and select “Telnet Client” check box.
To Do-----
We can create a basic network client that receives data from the internet.
Example:
import java.io.IOException;
import java.net.Socket;
import java.util.Scanner;

import org.omg.CORBA.portable.InputStream;


public class SocketExample {
       public static void main(String[] args)
           {
                     try
                     {
                  // Socket s = new Socket(serverName, port);
                           Socket s = new Socket("time-A.timefreq.bldrdoc.gov", 13);
                        try
                        {
                           InputStream inStream = (InputStream) s.getInputStream();
                           Scanner in = new Scanner(inStream);
             
                           while (in.hasNextLine())
                           {
                              String line = in.nextLine();
                              System.out.println(line);
                          }
                        }
                        finally
                        {
                           s.close();
                        }
                     }
              catch (IOException e)
              {
                 e.printStackTrace();
              }
           }
}
The output of this program is:
The statement:  Socket s = new Socket("time-A.timefreq.bldrdoc.gov", 13); Opens a socket which enables communication in or out of this program. Where the remote address of the server and 13 is is the port number on which we want to communicate. If connection fails it throws UnknownHostException which is subclass of IOException, we in this program catches only super class it will handle subclass errors also.

Once the socket is opened successfully the statement            
InputStream inStream = (InputStream) s.getInputStream(); Creates input stream and can be used to get input from the specified server line by line using method in.nextLine(); and displays output.

Implementing Servers
Now we will implement a server that can send information to clients. Once we start server program it waits for client to attach to its port. We can use port number 8189 which is not used by any other standard service.
Example:
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;

public class SocketExample {
       public static void main(String[] args)
       {
              try
              {
                     // create server socket
                     ServerSocket s = new ServerSocket(8189);
                          
                     // wait for client to connect
                     Socket incoming = s.accept();
                     try
                     {
                           InputStream inStream = (InputStream)                                                                                incoming.getInputStream();
                           OutputStream outStream = (OutputStream)                                                                      incoming.getOutputStream();
                            Scanner in = new Scanner(inStream);
                            PrintWriter out = new PrintWriter(outStream, true);
                            out.println("Hello! Enter BYE to exit.");
                            // echo client input
                      
                      boolean done = false;
                      while (!done && in.hasNextLine())
                      {
                            String line = in.nextLine();
                          out.println("Echo: " + line);
                          if (line.trim().equals("BYE")) done = true;
                      }
                  }
                  finally
                  {
                     incoming.close();
                  }
              }
           catch (IOException e)
           {
              e.printStackTrace();
           }
       }
}
The output of this system is:  
The statement: ServerSocket s = new ServerSocket(8189); Establish a server socket that monitors port 8189.
The statement: Socket incoming = s.accept(); Tells the program to wait for the client to connect to the specified port of the server. Once some client connects to the server over the network this method returns socket object. This object can be used to get input and output streams as shown in following statements:
 InputStream inStream = (InputStream) incoming.getInputStream();
OutputStream outStream = (OutputStream) incoming.getOutputStream();

Data send by server on server output stream becomes input of the client program. And every output of client’s output stream becomes input of server. We transfer data using sockets so we turn the stream into scanner and writer.
 The statement:  out.println("Hello! Enter BYE to exit.");
Send a message to client.
The statement: String line = in.nextLine(); Reads input from client program one line at a time.
The statement: out.println("Echo: " + line); Send data to client.
The statement: if (line.trim().equals("BYE")) done = true; checks the data received from client if it is equal to “BYE” then value of done variable is assigned true.

The statement: incoming.close(); Close the incoming socket.

Serving Multiple Clients
Sometimes we need to allow multiple clients to connect to our server. Server is constantly running and multiple clients from internet may need to use the server at the same time. We can do these using threads. Every time when program creates new socket connection, when call to access is successful, we launch a new thread to take care between server and that client. The main program will go back and wait for next connection.
Example:
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;

public class SocketExample {
       public static void main(String[] args)
       {
              try
                     {
                           int i = 1;
                           ServerSocket sSocket = new ServerSocket(8189);
                    
                           while (true)
                           {
                                  Socket incoming = sSocket.accept();
                             System.out.println("Spawning " + i);
                             Runnable r = new ThreadedEchoHandler(incoming);
                             Thread t = new Thread(r);
                             t.start();
                             i++;
                           }
                     }
                     catch (IOException e)
                     {
                           e.printStackTrace();
                     }
       }
}

/**
 This class handles the client input for one server socket connection.
*/
class ThreadedEchoHandler implements Runnable
{
       public ThreadedEchoHandler(Socket i)
       {
              incoming = i;
       }

       public void run()
       {
              try
              {
          try
          {
             InputStream inStream = incoming.getInputStream();
             OutputStream outStream = incoming.getOutputStream();

             Scanner in = new Scanner(inStream);
             PrintWriter out = new PrintWriter(outStream, true /* autoFlush */);

             out.println( "Enter 'BYE' to exit." );

             // echo client input
             boolean done = false;
             while (!done && in.hasNextLine())
             {
                String line = in.nextLine();
                out.println("Echo: " + line);
                if (line.trim().equals("BYE"))
                   done = true;
             }
          }
          finally
          {
             incoming.close();
          }
       }
       catch (IOException e)
       {
          e.printStackTrace();
       }
       }

    private Socket incoming;
 }
The output of the program:
The ThreadedEchoHandler class implements Runnable . It contains a loop which is sued for communication with the client in its run method. Each connection starts a new thread so multiple clients can get connected to the server.
Sending E-Mails
To send e-mail we make a socket connection with port 25 which is an SMTP (Simple Mail Transport Protocol) port. We can connect to any server which runs SMTP service.
Example:
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.net.*;
import java.io.*;
import javax.swing.*;

public class MailExample
{
       public static void main(String[] args)
       {
              JFrame frame = new MailTestFrame();
              frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
              frame.show();
       }
}


class MailTestFrame extends JFrame
{
       public MailTestFrame()
       {
              setSize(SIZE_WIDTH, SIZE_HEIGHT);
              setTitle("MailExample");

              getContentPane().setLayout(new GridBagLayout());

              GridBagConstraints gbCon = new GridBagConstraints();
              gbCon.fill = GridBagConstraints.HORIZONTAL;
              gbCon.weightx = 0;
              gbCon.weighty = 0;

              gbCon.weightx = 0;
              add(new JLabel("From:"), gbCon, 0, 0, 1, 1);
              gbCon.weightx = 100;
              from = new JTextField(20);
              add(from, gbCon, 1, 0, 1, 1);

              gbCon.weightx = 0;
              add(new JLabel("To:"), gbCon, 0, 1, 1, 1);
              gbCon.weightx = 100;
              to = new JTextField(20);
              add(to, gbCon, 1, 1, 1, 1);

              gbCon.weightx = 0;
              add(new JLabel("SMTP server:"), gbCon, 0, 2, 1, 1);
              gbCon.weightx = 100;
              smtpServerId = new JTextField(20);
              add(smtpServerId, gbCon, 1, 2, 1, 1);

              gbCon.fill = GridBagConstraints.BOTH;
              gbCon.weighty = 100;
              messageToSend = new JTextArea();
              add(new JScrollPane(messageToSend), gbCon, 0, 3, 2, 1);

              communication = new JTextArea();
              add(new JScrollPane(communication), gbCon, 0, 4, 2, 1);

              gbCon.weighty = 0;
              JButton sendButton = new JButton("Send");
              sendButton.addActionListener(new
             
              ActionListener()
              {
                     public void actionPerformed(ActionEvent evt)
                     {
                           new
                           Thread()
                           {
                                  public void run()
                                  {
                                         sendMail();
                                  }
                           }.start();
                     }
              });
              JPanel buttonPanel = new JPanel();
              buttonPanel.add(sendButton);
              add(buttonPanel, gbCon, 0, 5, 2, 1);
       }

       private void add(Component c, GridBagConstraints gbCon, int x, int y, int w, int h)
       {
              gbCon.gridx = x;
              gbCon.gridy = y;
              gbCon.gridwidth = w;
              gbCon.gridheight = h;
              getContentPane().add(c, gbCon);
       }

       public void sendMail()
       {
              try
              {
                     Socket s = new Socket(smtpServerId.getText(), 25);

                     outWriter = new PrintWriter(s.getOutputStream());
                     inReader = new BufferedReader(new
                                  InputStreamReader(s.getInputStream()));

                     String hostName
                           = InetAddress.getLocalHost().getHostName();

                     receive();
                     sendData("HELO " + hostName);
                     receive();
                     sendData("MAIL FROM: <" + from.getText() +">");
                     receive();
                     sendData("RCPT TO: <" + to.getText() +">");
                     receive();
                     sendData("DATA");
                     receive();
                     StringTokenizer tokenizer = new StringTokenizer(
                                  messageToSend.getText(), "\n");
                     while (tokenizer.hasMoreTokens())
                           sendData(tokenizer.nextToken());
                     sendData(".");
                     receive();
                     s.close();
              }
              catch (IOException exception)
              {
                     communication.append("Error: " + exception);
              }
       }

public void sendData(String s) throws IOException
{
       communication.append(s);
       communication.append("\n");
       outWriter.print(s);
       outWriter.print("\r\n");
       outWriter.flush();
}

public void receive() throws IOException
{
       String line = inReader.readLine();
       if (line != null)
       {
              communication.append(line);
              communication.append("\n");
       }
}
private BufferedReader inReader;
private PrintWriter outWriter;
private JTextField from;
private JTextField to;
private JTextField smtpServerId;
private JTextArea messageToSend;
private JTextArea communication;

public static final int SIZE_WIDTH = 300;
public static final int SIZE_HEIGHT = 300;
}
 Making URL Connections
URLS (uniform resource locators)
URL and URLConnection can be used to retrieving information from remote sites. For this purpose we will need to create an object of URL class such as:
URL webUrl = new URL(urlString);
openStream method of URL class is used to fetch information from the resource. This method returns object of InputStream.
InputStream inStreamObj = url.openStream();
Scanner in = new Scanner(inStreamObj);
Using object inStreamObj we can create scanner.
URIS (uniform resource identifiers)
URI contains several parts of the string specifying web source.  URL is a special kind of URI which contains sufficient information to locate a resource.