• Post Reply Bookmark Topic Watch Topic
  • New Topic

Singleton ( a Deeper Understanding )  RSS feed

 
Kamal Ahmed
Ranch Hand
Posts: 91
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,

I would highly appreciate if anyone can answer following questions regarding the Following code:
Also please note that the Driver (containing main()) is also included after this class.

1. Where should the getLine() method BODY go , so that if only one instance of SocketServer is instantiated i can access the accessor (get Methods) on it.

2. Should I move it INSIDE the default Constructor ? if not Why Not ?



import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.net.Socket;

public class SocketServer extends Thread {

// Private reference to the one and only instance called uniqueInstance
private static SocketServer uniqueInstance = null;

//Instance attributes
private Socket Client;
private String FileName;

public static SocketServer instance() {
if (uniqueInstance == null)
uniqueInstance = new SocketServer();
return uniqueInstance;
}

private SocketServer() {

}

public String getLine() {

//This part Needs to go to the Singleton Class, Since THAT is where this work is done, and if there is
//ONE Client requesting, the file, then the Singleton ONLY Sends out one line at a time,
// And if there are 2 Clients , then the Singleton Gives out 1 line per each, hence at a half rate
// to each Client

try {
DataOutputStream send =
new DataOutputStream(Client.getOutputStream());

BufferedReader in = new BufferedReader(new FileReader(FileName));
String str;
while ((str = in.readLine()) != null) {

try {
Thread.sleep(2000);
} catch (InterruptedException e) {
System.out.println("Exception" + e);
}

send.writeBytes(str + "\n");
}
in.close();

} catch (IOException e) {

}
System.out.println("Client Disconnected!");
return null;
}
/**
* @return
*/
public Socket getClient() {
return Client;
}

/**
* @return
*/
public String getFileName() {
return FileName;
}

/**
* @param socket
*/
public void setClient(Socket socket) {
Client = socket;
}

/**
* @param string
*/
public void setFileName(String string) {
FileName = string;
}

}


------------------------------------------------
import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Properties;

public class SocketDriver {
public static void main(String args[]) {

int port = 0; //Port as first Argument , >> 1000, typically 40001
String fileName = "";
//File Name of CheckPointFirewall File , used as input to this program
//Fourth Argument would be Duration in terms of Seconds, 0 meaning Continuous
if (args.length > 0)
port = Integer.parseInt(args[0]);
//System.out.println(port);
if (args.length > 1) {
fileName = args[1];
}

//Printing System Info

Properties p = System.getProperties();
System.out.println(p);

System.out.println("File Name = " + fileName);
ServerSocket serversocket;
Socket MyOwnClient;
String fMessage = "";
try {
serversocket = new ServerSocket(port);

try {
InetAddress local_Address = InetAddress.getLocalHost();
fMessage = "Local DNS Name = " + local_Address.toString();
} catch (UnknownHostException e) {
fMessage = "Unable to obtain Domain Name";
}

System.out.println("Accepting Connections...on port: " + port);
System.out.println(fMessage);
System.out.println("Starting to Accept Connections ....");
while (true) {

MyOwnClient = serversocket.accept();

System.out.println(
"Client Machine "
+ MyOwnClient.getInetAddress().getHostName()
+ " Connected!");

SocketServer instance = SocketServer.instance();

}
} catch (IOException e) {
System.out.println("Failed to Connect to socket!");
}
}
}

----------

Thanks,

-Kamal.
 
David Harkness
Ranch Hand
Posts: 1646
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Code that uses the SocketServer instance would call its static instance() method to acquire it and then make method calls on the returned SocketServer.

However, I think you're misunderstanding threading and singletons. First, your design allows only one Socket per SocketServer. If you call ss.setClient(socket), the old client's Socket is lost.

And then there's the fact that SS extends Thread but doesn't actually do any work in that thread. Any code that calls getLine() will perform the work in its own Thread instead of using SS's Thread. Any work that you want SS's Thread to perform must be initialiated by calling SS.start() and overriding Thread's run() method.

As an aside, unless you're altering Thread's basic behavior, it's generally preferable to implement Runnable and pass a reference to a new Thread. This way you can later use the object in a thread pool or multiple times or even from multiple threads simultaneously.

Can you describe what you want to do with more detail?
 
Kamal Ahmed
Ranch Hand
Posts: 91
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
David,

Thanks for your response. What I am trying to do is as Follows:

1. Wite a Socket Server, which accepts Socket Connections
2. The Socket Server should have 2 Arguments (on Command Line)
- port
- File Name

The File Name is the File Which is sent to the Client which makes the Connection

3. Make the Server Threaded
4. Make the Class Which Serves the File , a Singleton
so that when the First Client Makes a Connection, Line 1 thru N are sent
- When Second Client Makes a Connection , line are sent to the second Client which have NOT been sent , i.e the lines sent to the first Client are not sent to the second Client.

When a third Client Makes a Connection , lines which are sent to the First and Second Client are not sent to the Third Client.
and so on....

Thanks,

-Kamal.
 
David Harkness
Ranch Hand
Posts: 1646
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Okay, I think I understand where you're going with this. Basically, the server streams the file line-by-line to whichever client is currently connected. At any point, another client can connect to the server, bump off the other client, and start getting the stream from the same place in the file where the other client got cut off. Is that right?

For the server, using this method you'll need two threads. One thread accepts connections on the ServerSocket; the other streams the file to the connected client. When a new connection is made, the accepting thread needs to pass the new socket to streaming class.

I recommend splitting apart SocketServer into two classes modeled after the previous paragraph. One accepts connections, and the other streams the file. You could combine them, but they have different responsibilities. Just make both a singleton or store a reference to the streamer in the listener.

The tricky part will be writing a Streamer.setSocket(Socket) method that will disconnect and swap out the old Socket and recreate the necessary OutputStream. In fact, you may want to swap PrintWriter for the DataOutputStream so you can use println(line), but that's just my personal opinion. I don't know how you've written the client, so you'll have to decide.
 
It is sorta covered in the JavaRanch Style Guide.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!