Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 357
  • Last Modified:

Java Sockets with Threading

Hi,
  I have created a client program (applet) that connects to a server program and checks to see if a couple of files exist on the server. This works fine with just one client connected to the server, however if possible I want to have multiple clients connected to the server program. I have tried to achieve this through threading:

- client and server connect on a listening port.
- server sends back a free port to connect on to client
- client and server connect on new port and start new thread.

However this is the bit of the program that does not work. The code is as follows:

SERVER

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

public class WIS1 {

  static final int LISTENING_PORT = 7777;
  //static int COMMUNICATION_PORT = LISTENING_PORT;
  static int COMMUNICATION_PORT = 7778;

//**********************************************************

  public static void main(String args[]) {

     String tempstring = null;

     ServerSocket listener;
     Socket connection;
     Socket connection2;
     BufferedReader Incoming;

     try {
      listener = new ServerSocket(LISTENING_PORT);
      System.out.println("Listening on port " + LISTENING_PORT);
      while (true) {
        //accept connection on listening port
      System.out.println("got to point");
        connection = listener.accept();
      System.out.println(COMMUNICATION_PORT);
      //send communication port back to client
      PrintStream outgoing = new PrintStream(connection.getOutputStream() );
      outgoing.println(COMMUNICATION_PORT);
      connection.close();
      System.out.println(COMMUNICATION_PORT);
      //connects on new communication port
      listener = new ServerSocket(COMMUNICATION_PORT);
      //increments connection port by one
      COMMUNICATION_PORT++;
        System.out.println(COMMUNICATION_PORT);
      connection2 = listener.accept();
      //starts up new thread on communication port
        new ConnectionHandler(connection2);
      }
     }
     catch (IOException e) {
      System.out.println("Server shut down unexpectedly");
      System.out.println("Error : " + e);
      return;
     }
  }

//**********************************************************

  static class ConnectionHandler extends Thread {

    File directory = null;
    Socket connection2;
    Reader incoming;
    PrintWriter outgoing;

    ConnectionHandler (Socket conn) {

      connection2 = conn;
      start();
    }


//*****

  void CheckOutputFile(String Filename) throws Exception {

    File file = new File(Filename);

    //to check if overwrite use file.canWrite()

    System.out.println("checking output file : " + file);

    if ((! file.exists()) || (file.isDirectory()) || (! file.canWrite())) {
      outgoing.println("OUTPUT_FILE_ERR");
      System.out.println("Output file Error");
    }
    else {

      outgoing.println("OUTPUT_FILE_ACK");
      System.out.println("Output file OK");

    }

    outgoing.flush();

  }


//*****

  void CheckInputFile(String Filename) throws Exception {

    File file = new File(Filename);

    System.out.println("checking input file : " + file);

    if ((! file.exists()) || (file.isDirectory()) || (! file.canRead())) {
      outgoing.println("INPUT_FILE_ERR");
      System.out.println("Input file Error");
    }
    else {
      outgoing.println("INPUT_FILE_ACK");
      System.out.println("Input file OK");
    }

    outgoing.flush();

  }

//*****

//**********************************************************

 public void run() {

   String command = null;
   BufferedReader incoming;


   try {

     incoming = new BufferedReader(new InputStreamReader(connection2.getInputStream()));
     outgoing = new PrintWriter( connection2.getOutputStream() );
     command = incoming.readLine();

     if (command.startsWith("input")) {
       String filename = command.substring(5).trim();
       CheckInputFile(filename);
     }

     command = incoming.readLine();

     if (command.startsWith("output")) {
       String filename = command.substring(6).trim();
       CheckOutputFile(filename);
     }
     else {
       outgoing.println("Unknown command");
       outgoing.flush();
     }
     System.out.println("OK   " + connection2.getInetAddress() + " " + command);
   }
   catch (Exception e) {

     System.out.println("Error " + connection2.getInetAddress() + " " + command + " " + e);
   }
   finally {
     try {
       connection2.close();
       System.out.println("Connection closed");
     }
     catch (IOException e) {
       System.out.println("Error" + e);
     }
   }

 }

//**********************************************************

 }

}


CLIENT

import java.awt.*;
import java.applet.Applet;
import java.awt.Label;
import java.net.*;
import java.io.*;
import java.lang.*;
import java.awt.event.*;

public class GUI extends Applet
  implements ActionListener {

  static final int LISTENING_PORT = 7777;

  Label headingLabel = new Label("            Web Interface Client 8              ");
  Label IPlabel = new Label("IP Address :        ");
  TextField IP = new TextField("127.0.0.1",20);
  Label InputLabel = new Label("Input File :        ");
  TextField inputfile = new TextField(20);
  Label OutputLabel = new Label("Output File :       ");
  TextField outputfile = new TextField(20);
  Button OverwriteButton = new Button("OverWrite");
  Button ConnectButton = new Button("Connect");
  Label InfoLabel = new Label("Information :                                     ");
  TextArea info = new TextArea(10,35);



  public void init() {

    setBackground(Color.white);
    add(headingLabel);
    add(IPlabel);
    add(IP);
    add(InputLabel);
    add(inputfile);
    add(OutputLabel);
    add(outputfile);
    add(OverwriteButton);
    OverwriteButton.setVisible(false);
    add(ConnectButton);
    add(InfoLabel);
    add(info);
    ConnectButton.addActionListener(this);

    }

  public void actionPerformed(ActionEvent event) {

    try {
    if (event.getSource() == ConnectButton)
      code();
    }
    catch (Exception e){
      info.append("error here" + e.toString());
    }

  }

//**********************************************************

  public void code() {

    String computer = null;
    Socket connection;
    Socket connection2;
    String temp = null;
    int COMM_PORT;

    computer = IP.getText();

    if ((inputfile.getText().equals("")) || (outputfile.getText().equals(""))) {

      if (inputfile.getText().equals("")) {
        info.append("ERROR : Please input an Input File" + "\n");
      }
      if (outputfile.getText().equals("")){
        info.append("ERROR : Please input an Output File" + "\n");
      }

    }
    else {

      info.append("Connecting to server on IP: " + computer+"\n");
      info.append("Using port number : " + LISTENING_PORT + "\n");
      info.append("Input file : " + inputfile.getText() + "\n");
      info.append("Output file : " + outputfile.getText() + "\n");


      try {
        //connects on listening port
        info.append("Trying to connect on port :"+ LISTENING_PORT + " to IP: " + computer +"\n");
        connection = new Socket(computer,LISTENING_PORT);
      info.append("got to point");
      //gets new port to connect on from the server
        BufferedReader incoming = new BufferedReader(new InputStreamReader(connection.getInputStream()));
        temp = incoming.readLine();
      info.append("got :" + temp + "\n");
      COMM_PORT = Integer.valueOf(temp).intValue();
      info.append(COMM_PORT + "\n");
      connection.close();
      //connect on new port
      connection2 = new Socket(computer,COMM_PORT);
        new ConnectionHandler(connection2);
      }
      catch (IOException e) {
        info.append("Error : " + e + "\n");
      }
    }

  }

//**********************************************************

  public class ConnectionHandler {

    Socket connection2;
    Reader incoming;
    PrintWriter outgoing;

    ConnectionHandler(Socket conn){

      info.append("Connected" + "\n");
      connection2 = conn;

    String inputfilename = null;
    String outputfilename = null;
    String command = null;

    inputfilename = inputfile.getText();
    outputfilename = outputfile.getText();

    //Check input file

    String datasend = ("input" + inputfilename);

    try {
      BufferedReader incoming = new BufferedReader(new InputStreamReader(connection2.getInputStream()));
      outgoing = new PrintWriter( connection2.getOutputStream() );
      outgoing.println(datasend);
      outgoing.flush();
      command = incoming.readLine();
    }
    catch (Exception e) {
      info.append("Error " + connection2.getInetAddress() + " " + command + " " + e + "\n");
    }

    if (command.equals("INPUT_FILE_ERR")) {
      info.append("Please enter a valid input file \n");
    }
    else {
      info.append("input file valid \n");
    }


    //Check Output file

    datasend = ("output" + outputfilename);
    command = null;

    try {
     BufferedReader incoming = new BufferedReader(new InputStreamReader(connection2.getInputStream()));
     outgoing = new PrintWriter(connection2.getOutputStream());
     outgoing.println(datasend);
     outgoing.flush();
     command = incoming.readLine();
    }
    catch (Exception e) {
      info.append("Error " + connection2.getInetAddress() + " " + command + " " + e + "\n");
    }
   
    if (command.equals("OUTPUT_FILE_ERR")) {
      info.append("Please enter a valid output file \n");
    }
    else {
      OverwriteButton.setVisible(true);
      info.append("output file valid \n");
    }
   
    try {
      info.append("connection closed \n");
      connection2.close();
    }
    catch (Exception e) {
      info.append("Error " + e);
    }

  }

  }
 
//**********************************************************
}

Any help would be greatly appreciated

Thanks

Dan
0
danny1979
Asked:
danny1979
  • 5
1 Solution
 
fivesigmaeventCommented:
Try using this in your server:

try
{
   while(true)
   {
      listener = new ServerSocket(LISTENING_PORT,num_connections );
      Socket connection = listener.accept();
      ConnectionHandler c = new ConnectionHandler(connection);
   }
}
catch(IOException e)
{ System.out.println("Exception while listening for connections."
}

The ServerSocket will allow a max of num_connections connections. When a connection is accepted from the server socket, start a thread and pass in the new socket.

0
 
fivesigmaeventCommented:
My apologies. After re-reading I realize it should be slightly different. Put the ServerSocket object in your constructor. Make sure num_connections is set to max num of allowable connections. Hope this helps.

public WIS1()
{
try
{
   listener = new ServerSocket(LISTENING_PORT, num_connections );
}
catch(IOException e )
{
   System.out.println( "Exception creating server socket." );
}
try
{
   while(true)
   {
      Socket connection = listener.accept();
      ConnectionHandler c = new ConnectionHandler(connection);
   }
}
catch(IOException e)
{
   System.out.println("Exception while listening for connections." );
}

0
 
fivesigmaeventCommented:
Added comments to make it clearer.

ServerSocket listener;
int num_connections;

public WIS1()
{ // constructor
  try
  {
    num_connections = 2;
    // get a server socket, allow upto 2 connections
    listener = new ServerSocket(LISTENING_PORT, num_connections );
  }
  catch(IOException e )
  {
    System.out.println( "Exception creating server socket." );
  }
}

// put this is main or other method that runs the server
try
{
  while(true)
  { // run forever, listening and accepting client connections
      Socket connection = listener.accept();
      // connection has been accepted; start a thread to deal with client
      ConnectionHandler c = new ConnectionHandler(connection);
  }
}
catch(IOException e)
{
  System.out.println("Exception while listening for connections." );
}


Let me know if you have any questions.
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
fivesigmaeventCommented:
danny,

checking up on you to see how you made out.
0
 
danny1979Author Commented:
Sorry, have not got time to try it out today, but will certainly give this a go in the morning. Just a couple of questions:

1) Have many connections can you have on a single port?
2) Is this solution more pratical/efficient/effective solution than opening a new port for each connection?

Thanks a lot for your help, will give you the points as soon as I try it out tommorrow.

Dan
0
 
bkrahmerCommented:
Dan, The solution posted is great.  Use it.  :)  Maximum connections?  Thousands.  It depends upon a lot of factors like what OS/version, memory, Java version, JVM, etc.
brian
0
 
fivesigmaeventCommented:
danny,

As bkrahmer mentioned, the number of max connections could vary. A project would have to be doing some pretty heavy-duty stuff to use or exceed the max amount connections.

In response to part 2), a ServerSocket was allocated twice and 2 port numbers were specified. That is uneccessary. The ServerSocket in your code need only be allocated once and only 1 port number used. When a connection is accepted from the SocketServer, it allocates a new Socket that automatically uses some new port number. That Socket is passed to a newly launched thread for communicating to a client. The ServerSocket continues listenting to the same port as before.

Hope that helps.
0

Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

  • 5
Tackle projects and never again get stuck behind a technical roadblock.
Join Now