Forums Register Login

Singleton ( a Deeper Understanding )

+Pie Number of slices to send: Send
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.
+Pie Number of slices to send: Send
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?
+Pie Number of slices to send: Send
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.
+Pie Number of slices to send: Send
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.
roses are red, violets are blue. Some poems rhyme and some are a tiny ad:
a bit of art, as a gift, that will fit in a stocking
https://gardener-gift.com


reply
reply
This thread has been viewed 795 times.
Similar Threads
Java net BindException:Address already in use: JVM_Bind
HTTP Client/Server Problem
Reseting socket after few seconds
Socket Server Serving Numbers
Socket is not receiving the first request after long Ideal time
More...

All times above are in ranch (not your local) time.
The current ranch time is
Mar 19, 2024 02:02:59.