?
Solved

Java Sockets with Threading

Posted on 2003-02-24
7
Medium Priority
?
337 Views
Last Modified: 2010-03-31
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
Comment
Question by:danny1979
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
7 Comments
 

Expert Comment

by:fivesigmaevent
ID: 8010231
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
 

Expert Comment

by:fivesigmaevent
ID: 8010501
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
 

Accepted Solution

by:
fivesigmaevent earned 300 total points
ID: 8010590
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
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Expert Comment

by:fivesigmaevent
ID: 8022927
danny,

checking up on you to see how you made out.
0
 

Author Comment

by:danny1979
ID: 8024776
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
 
LVL 2

Expert Comment

by:bkrahmer
ID: 8039545
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
 

Expert Comment

by:fivesigmaevent
ID: 8043259
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

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

By the end of 1980s, object oriented programming using languages like C++, Simula69 and ObjectPascal gained momentum. It looked like programmers finally found the perfect language. C++ successfully combined the object oriented principles of Simula w…
Introduction This article is the second of three articles that explain why and how the Experts Exchange QA Team does test automation for our web site. This article covers the basic installation and configuration of the test automation tools used by…
Viewers learn how to read error messages and identify possible mistakes that could cause hours of frustration. Coding is as much about debugging your code as it is about writing it. Define Error Message: Line Numbers: Type of Error: Break Down…
Viewers will learn about if statements in Java and their use The if statement: The condition required to create an if statement: Variations of if statements: An example using if statements:
Suggested Courses
Course of the Month14 days, 12 hours left to enroll

770 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question