Closing resources when thread is finished in Java - java

I have a thread that uses network port for communication. I added
cancel() method to stop the execution and close network resources (How to properly stop the Thread in Java?)
private class ServerThread extends Thread {
int portNumber;
String serverAddress = null;
public ServerThread(String serverAddress, int portNumber) {
super();
this.serverAddress = "localhost";
this.portNumber = portNumber;
}
#Override
public void run() {
ServerSocket listener;
Socket socket;
try {
listener = new ServerSocket(this.portNumber);
socket = listener.accept();
BufferedReader in = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
PrintWriter out = new PrintWriter(socket.getOutputStream(),
true);
while (!isInterrupted()) {
String input = in.readLine();
if (input != null) {
out.println(input);
System.out.println("Hi:" + input);
}
} // end of while loop
System.out.println("OUT"); <-- ???
socket.close(); <-- ???
listener.close(); <-- ???
} catch (IOException e) {
e.printStackTrace();
}
}
public void cancel() {
System.out.println("cancel called");
interrupt();
}
}
The issue is that when I execute the ServerThread, and send cancel() message to finish the execution, it seems like that the three lines of code never executed: System.out.println("OUT"); socket.close(); listener.close();.
It also seems like that I don't need to send cancel() message to finish the thread.
ServerThread s = new ServerThread(serverAddress, serverPortNumber);
s.start();
...
s.cancel(); // ???
What's the recommended way of closing resources used by threads?
Don't I have to close resources when thread is not used anymore? Or everything is just automatically processed?
ADDED
It seems like that the thread is killed automatically as this code just works.
while(true) {
String input = in.readLine();
if (input != null) {
System.out.println("Received:" + input);
out.println(input);
}
} // end of while loop
/* System.out.println("OUT");
socket.close();
listener.close(); */

Thread#interrupt() will not interrupt the blocking I/O call on the socket. Try setting a "stop" flag and closing the socket in the cancel() method instead, and deal with the exception and check the flag in the while loop.
InterruptibleChannels reacts on the interrupt call, but not "old fashioned" socket streams.

In Java 7 you can use the try (resource) {} catch idiom like this:
try (final BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()))) {
while ((line = reader.readLine()) != null) {
process(line);
}
} catch (IOException e) {
e.printStackTrace();
}
This will guarantee that the stream is closed properly once the try block is left. No matter what happens inside or how the try/catch terminates.

Related

HTTP1.1 Connection:keepalive implement with java occurs withjava.net.SocketTimeoutException: Read timed out

I'm implement a http server with version1.1 using java socket programming. I use a version 1.0 sample code and I want add the persistent connection feature by not closing socket utilt a "Connection : close" send to the server. However, I came accross with "java.net.SocketTimeoutException: Read timed out" info after an input like"localhost:8080/xxxx" on my browser and not receiving anything when tested with a client program. Code is too long, and I mention the matter parts bellow! Can you find the problems for me, thanks!!!
////////here is the server part using thread pool techs
//Webserver class
protected static Properties props = new Properties();
/* Where worker threads stand idle */
static Vector threads = new Vector();
public static void main(String[] a) throws Exception {
int port = 8080;
if (a.length > 0) {
port = Integer.parseInt(a[0]);
}
loadProps();
printProps();
/* start worker threads */
for (int i = 0; i < workers; ++i) {
Worker w = new Worker();
(new Thread(w, "worker #"+i)).start();
threads.addElement(w);
}
ServerSocket ss = new ServerSocket(port);
while (true) {
Socket s = ss.accept();
Worker w = null;
synchronized (threads) {
if (threads.isEmpty()) {
Worker ws = new Worker();
ws.setSocket(s);
(new Thread(ws, "additional worker")).start();
} else {
w = (Worker) threads.elementAt(0);
threads.removeElementAt(0);
w.setSocket(s);
}
}
}
}
//Worker class inherit from Webserver class
byte[] buf;
Worker() {
buf = new byte[BUF_SIZE];
s = null;
}
synchronized void setSocket(Socket s) {
this.s = s;
notify();
}
public synchronized void run() {
while(true) {
if (s == null) {
/* nothing to do */
try {
wait();
} catch (InterruptedException e) {
/* should not happen */
continue;
}
}
try {
handleClient();
} catch (Exception e) {
e.printStackTrace();
}
/* go back in wait queue if there's fewer
* than numHandler connections.
*/
if(!headAttri.getPersistConnec())
s = null;
//
Vector pool = WebServer.threads;
synchronized (pool) {
if (pool.size() >= WebServer.workers) {
/* too many threads, exit this one */
try{
if(s != null)
s.close();
}catch (IOException e) {
e.printStackTrace();
}
return;
} else {
if(!headAttri.getPersistConnec())
pool.addElement(this);
}
}
}
}
//in handle client I mention the socket handles here(s is the socket)
void handleClient() throws IOException {
//...
s.setSoTimeout(WebServer.timeout);
s.setTcpNoDelay(true);
//...
try{
//...handle request and response the client
//...
}finally{
//close socket if head info "Connection: close" is found
if(headAttri.getPersistConnec()){
s.setKeepAlive(true);
}
else{
s.close();
}
}
}
//////////end server part
//////here is the client part
public SimpleSocketClient()
{
String testServerName = "localhost";
int port = 8080;
try
{
// open a socket
Socket socket = openSocket(testServerName, port);
// write-to, and read-from the socket.
// in this case just write a simple command to a web server.
String result = writeToAndReadFromSocket(socket, request_str[1]);
// print out the result we got back from the server
System.out.println(result);
// close the socket, and we're done
socket.close();
}
catch (Exception e)
{
e.printStackTrace();
}
}
private Socket openSocket(String server, int port) throws Exception
{
Socket socket;
// create a socket with a timeout
try
{
InetAddress inteAddress = InetAddress.getByName(server);
SocketAddress socketAddress = new InetSocketAddress(inteAddress, port);
// create a socket
socket = new Socket();
// this method will block no more than timeout ms.
int timeoutInMs = 10*1000; // 10 seconds
socket.connect(socketAddress, timeoutInMs);
return socket;
}
catch (SocketTimeoutException ste)
{
System.err.println("Timed out waiting for the socket.");
ste.printStackTrace();
throw ste;
}
}
private String writeToAndReadFromSocket(Socket socket, String writeTo) throws Exception
{
try
{
// write text to the socket
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
bufferedWriter.write(writeTo);
bufferedWriter.flush();
//test
//bufferedWriter.write("GET src/WebServer.java HTTP/1.1\r\nHost: localhost\r\nConnection: close");
//bufferedWriter.flush();
// read text from the socket
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
StringBuilder sb = new StringBuilder();
//string handling code
String str;
while ((str = bufferedReader.readLine()) != null)
{
sb.append(str + "\n");
}
// close the reader, and return the results as a String
bufferedReader.close();
return sb.toString();
}
catch (IOException e)
{
e.printStackTrace();
throw e;
}
}
////end client part
//close socket if head info "Connection: close" is found
if(headAttri.getPersistConnec()){
s.setKeepAlive(true);
It is hard to tell from your code what you are really doing but based on this code fragment it looks like you are mixing up HTTP keep alive (i.e. Connection: keep-alive handling, multiple requests in a single TCP connection) with TCP keep alive (detect broken TCP connection). See Relation between HTTP Keep Alive duration and TCP timeout duration and HTTP Keep Alive and TCP keep alive for explanations about the difference.
I want add the persistent connection feature by not closing socket utilt a "Connection : close" send to the server
That's not how you do it. You have to close the connection yourself, either
after a request with a Connection: close header is received and you've sent the response, or
when you get a read timeout on the socket reading the next request.
The length of the read timeout is entirely up to you, because it is up to you to protect yourself from DOS attacks among other things.
NB calling Socket.setKeepAlive(true) has absolutely nothing whatsoever to do with it.
NB 2 You should look into java.util.concurrent.Executor rather than implement your own thread pool.

Handling sockets in java

I am creating a socket to a server in java and after the socket is connected it creates a new thread which can access the socket input and output stream and this thread then blocks and processes the input lines when they come in.
I understand that the readln method on the BufferedReader will return null when the input stream ends. This doesn't necessarily mean that the socket is closed though does it? What does this mean? So I would then want to run the close method on the socket to close it nicely.
I also understand that the readln method can throw an IOException and that this is thrown after the close method is called on a socket if it is currently blocking. When else can this be thrown? Could the socket still be open after this is thrown or would it always be closed and ready for garbage collection etc.
This is the code I have at the moment and I don't really know how to handle disconnects properly. At the moment I think this could end up in a deadlock if the disconnect method is called whilst the socket is waiting for a line because disconnect will call close on the socket. This will then throw the IOException on readLine and this will then result in that catch block calling disconnect again.
public class SocketManager {
private Socket socket = null;
private PrintWriter out = null;
private BufferedReader in = null;
private String ip;
private int port;
private Object socketLock = new Object();
public SocketManager(String ip, int port) {
this.ip = ip;
this.port = port;
}
public void connect() throws UnableToConnectException, AlreadyConnectedException {
synchronized(socketLock) {
if (socket == null || socket.isClosed()) {
throw (new AlreadyConnectedException());
}
try {
socket = new Socket(ip, port);
out = new PrintWriter(socket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
} catch (IOException e) {
throw (new UnableToConnectException());
}
new Thread(new SocketThread()).start();
}
}
public void disconnect() throws NotConnectedException {
synchronized(socketLock) {
if (isConnected()) {
throw (new NotConnectedException());
}
try {
socket.close();
} catch (IOException e) {}
}
}
public boolean isConnected() {
synchronized(socketLock) {
return (socket != null && !socket.isClosed());
}
}
private class SocketThread implements Runnable {
#Override
public void run() {
String inputLine = null;
try {
while((inputLine = in.readLine()) != null) {
// do stuff
}
if (isConnected()) {
try {
disconnect();
} catch (NotConnectedException e) {}
}
} catch (IOException e) {
// try and disconnect (if not already disconnected) and end thread
if (isConnected()) {
try {
disconnect();
} catch (NotConnectedException e1) {}
}
}
}
}
}
I basically want to know the best way of achieving the following:
Writing a connect method that connects to a socket and starts a separate thread listening for input.
Writing a disconnect method that disconnects from the socket and terminates the thread that's listening for input.
Handling the scenario of the connection to the remote socket being broken.
I have read through the java tutorial on sockets but in my opinion it doesn't really cover these in much detail.
Thanks!
When I said that it could end up as a deadlock I think I was wrong.
What would happen is:
disconnect() called whilst in.readLine() blocking
socket.close() executed.
in.readline() throws IOException.
I was then thinking that the exception handler in the SocketThread would call disconnect whilst disconnect is waiting for that exception to finish. It wouldn't matter through because they are both different threads so the code in disconnect() would continue whilst the exception is being caught in the SocketThread. The SocketThread would then call disconnect() but would then have to wait until the first instance of disconnect() finished. Then disconnect() would execute again but would get the NotConnectedException thrown which would be caught in the SocketThread and nothing would happen. The SocketThread would exit and that's the wanted result.
However I have looked into the socket class and it also contains these methods:
shutdownInput()
shutdownOutput()
shutdownInput() sends the end EOF symbol into the input stream meaning in.readline() returns null and the loop exits cleanly. shutdownOutput() sends the TCP termination sequence informing the server that it's disconnecting.
Calling both of these before socket.close() makes more sense because it means the thread will exit nicely instead of exiting as a result of an exception being thrown which has more overhead.
So this is the modified code:
public class SocketManager {
private Socket socket = null;
private PrintWriter out = null;
private BufferedReader in = null;
private String ip;
private int port;
private Object socketLock = new Object();
public SocketManager(String ip, int port) {
this.ip = ip;
this.port = port;
}
public void connect() throws UnableToConnectException, AlreadyConnectedException {
synchronized(socketLock) {
if (socket == null || socket.isClosed()) {
throw (new AlreadyConnectedException());
}
try {
socket = new Socket(ip, port);
out = new PrintWriter(socket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
} catch (IOException e) {
throw (new UnableToConnectException());
}
new Thread(new SocketThread()).start();
}
}
public void disconnect() throws NotConnectedException {
synchronized(socketLock) {
if (isConnected()) {
throw (new NotConnectedException());
}
try {
socket.shutdownInput();
} catch (IOException e) {}
try {
socket.shutdownOutput();
} catch (IOException e) {}
try {
socket.close();
} catch (IOException e) {}
}
}
public boolean isConnected() {
synchronized(socketLock) {
return (socket != null && !socket.isClosed());
}
}
private class SocketThread implements Runnable {
#Override
public void run() {
String inputLine = null;
try {
while((inputLine = in.readLine()) != null) {
// do stuff (probably in another thread)
}
// it will get here if socket.shutdownInput() has been called (in disconnect)
// or possibly when the server disconnects the clients
// if it is here as a result of socket.shutdownInput() in disconnect()
// then isConnected() will block until disconnect() finishes.
// then isConnected() will return false and the thread will terminate.
// if it ended up here because the server disconnected the client then
// isConnected() won't block and return true meaning that disconnect()
// will be called and the socket will be completely closed
if (isConnected()) {
try {
disconnect();
} catch (NotConnectedException e) {}
}
} catch (IOException e) {
// try and disconnect (if not already disconnected) and end thread
if (isConnected()) {
try {
disconnect();
} catch (NotConnectedException e1) {}
}
}
}
}
}
In order to be sure that all resources associated with the socket are relased you have to call close() method when you finish work with that socket.
Typical IO exception handling pattern is that you catch it and then perform best efforts to clean everything calling close() method.
So the only thing you have to do is to ensure that you call close() on every socket during it's lifetime.
You're on the right track. I wouldn't use "readline", only raw read, and "do stuff"
should be limited to constructing a queue of received data. Likewise writing replies
ought to be a separate thread that empties a queue of data to be sent.
Despite socket's guarantees of integrity, stuff will go wrong and you'll sometimes receive data that doesn't make sense. There's a crapload of stuff below "read" and "write" and no system is perfect or bug free. Add your own wrapper with checksums at the level of YOUR read and write so you can be sure you're receiving what was intended to be sent.

Java: Synchronizing socket input

My first attempt at writing a client for a php socket server and I'm running into a little trouble and I'm sort of being flooded with info!
With the server, we want an open connection, I want my client end to wait until it receives data before notifying the thread to start parsing the input-stream. Is this achievable without using a loop? I'd rather be able to call lock.notify().
I was also looking at NIO, is this a viable option for what I want?
Here's the code I have so far, but again, I'm just trying to avoid the for(;;) and maybe even queue the received messages as they will most likely just be JSON
Thread serverRecieve = new Thread(new Runnable() {
#Override
public void run() {
try {
for (;;) {
if (in != null) {
String line;
while ((line = in.readLine()) != null) {
sout(line);
}
} else {
sout("inputstream is null! Waiting for a second to test again");
}
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
Logger.getLogger(WebManager.class.getName()).log(Level.SEVERE, null, ex);
}
}
} catch (IOException ex) {
Logger.getLogger(WebManager.class.getName()).log(Level.SEVERE, null, ex);
}
}
});
Thanks guys!
PS: I did look through A LOT of socket threads on here but decided it would be easier just to ask what I need.
I think you can use a while loop and put a condition using in != null as:
while(in == null){
//wait for a second before checking the in stream again
try {
sout("inputstream is null! Waiting for a second to test again");
Thread.sleep(1000);
} catch (InterruptedException ex) {
Logger.getLogger(WebManager.class.getName()).log(Level.SEVERE, null, ex);
}
}
//now your in is available. Read the data and proceed
String line = null;
while ((line = in.readLine()) != null) {
sout(line);
}
The first while loop will terminate as soon in stream is available.
How about creating dedicated subtype of Runnable for reading from socket, like this:
class Reader implements Runnable {
private final Socket socket;
private volatile boolean stopped;
Reader(Socket socket) {
this.socket = socket;
}
#Override
public void run() {
try {
while (true) {
int in = socket.getInputStream().read();
// process in here
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (!stopped) socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void stop() {
try {
stopped = true;
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
class Client {
private volatile Reader reader;
void start() {
reader = new Reader(new Socket(serverHost, serverPort));
Thread readerThread = new Thread(reader, "Reader-thread");
readerThread.start();
}
void stop() {
Reader reader = this.reader;
// reader.stop() will close socket making `run()` method finish because of IOException
// reader.socket is final, thus we have proper visibility of it's values across threads
if (reader != null) reader.stop();
}
}

Opening read/write streams multiple times from a Socket

In a class where I have ServerSocket listening for incoming connections, following is the code:
while(isRunning)
{
try
{
Socket s = mysocketserver.accept();
acknowledgeClient(s);
new ClientHandler(s).start(); //Start new thread to serve the client, and get back to accept new connections.
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
And following is acknowledgeClient(Socket s) code.
ObjectInputStream in = new ObjectInputStream(s.getInputStream);
ObjectOutputStream out = new ObjectOutputStream(s.getOutStream);
String msg = in.readObject().toString();
System.out.println(msg+" is Connected"); //Show who's connected
out.writeObject("success"); //Respond with success.
in.close();
out.close();
The run() method of the ClientHandler.
try
{
in = new ObjectInputStream(client.getInputStream());
out = new ObjectOutputstream(client.getOutputStream());
String msg = "";
while(!msg.equalsIgnoreCase("bye"))
{
msg = in.readObject().toString();
System.out.println("Client Says - "+msg);
out.writeObject("success");
}
in.close();
out.close();
}
catch(Exception ex)
{
ex.printStackTrace();
}
And following is the way how client program communicates with this Echo Server.
try
{
int count = 10;
client = new Socket("localhost",8666);
in = new ObjectInputStream(client.getInputStream());
out = new ObjectOutputstream(client.getOutputStream());
out.writeObject("Foo");
System.out.println("Connection Status : "+in.readObject().toString());
while(count>0)
{
out.writeObject("Hello!");
String resp = in.readObject().toString(); //Getting EOFException here.
System.out.println("Sent with :"+resp);
count--;
Thread.sleep(1000);
}
out.close();
in.close();
client.close();
}
catch(Exception ex)
{
ex.printStackTrace();
}
As you might have noticed that, after the client is acknowledged after connection, I close the read/write streams, and from new thread which is serving the client, I'm opening the stream again, and from the server reading/writing from the connected socket is started, but as soon as I attempt to read server's response on sending Hello! by client, it crashes with EOFException instead of getting success.
I know the causes for which EOF occurs but not getting the clue that why is it happening here, I'm not attempting to read socket that has nothing in its stream (it should have success as written by server).
Is it too early that client is attempting to read socket before server has printed Hello! on its end and written success as response?
P.S. : I know its not a good way to ask question by putting so much code, we're expected here to get answers of the issue and understand it rather than having our problem fixed by others and get away. So, I've provided this much code to show all aspects from the problem.
I studied the source code of ObjectInputStream, and it appears that the reference to the original input stream s.getInputStream() is stored inside the ObjectInputStream.
When you close the ObjectInputStream, s.getInputStream() is closed as well.
Once an input stream is closed, it cannot be opened again. Thus, you get an EOFException, which indicates that you are at the end of the stream (since the stream could not be opened again).
You should do something like this to acknowledge the client.
Inside the run() method of the ClientHandler:
try {
// acknowledge client
ObjectInputStream in = new ObjectInputStream(s.getInputStream());
ObjectOutputStream out = new ObjectOutputStream(s.getOutStream());
String msg = in.readObject().toString();
System.out.println(msg+" is Connected"); //Show who's connected
out.writeObject("success"); //Respond with success.
// end acknowledge client
String msg = "";
while(!msg.equalsIgnoreCase("bye"))
{
msg = in.readObject().toString();
System.out.println("Client Says - "+msg);
out.writeObject("success");
}
in.close();
out.close();
}
catch(Exception ex)
{
ex.printStackTrace();
}
If you want to isolate the acknowledge code in a seperate method, just be sure to maintain a proper reference to the same ObjectInputStream without closing the stream, then pass the reference around.
I'm opening the stream again, and from the server reading/writing from the connected socket is started,
Once a stream is close, you can't open it again. In fact you can't use two Object stream on the same stream this way at all.
Instead you should create an object stream for input and output once and only once and not close it until you have finished.
Well take a look at this program, i wrote it to understand multiple clients and server communication, your question is answered in this program.
The Client side code
public class ClientWala {
public static void main(String[] args) throws Exception{
Boolean b = true;
Socket s = new Socket("127.0.0.1", 4444);
System.out.println("connected: "+s.isConnected());
OutputStream output = s.getOutputStream();
PrintWriter pw = new PrintWriter(output,true);
// to write data to server
while(b){
if (!b){
System.exit(0);
}
else {
pw.write(new Scanner(System.in).nextLine());
}
}
// to read data from server
InputStream input = s.getInputStream();
InputStreamReader isr = new InputStreamReader(input);
BufferedReader br = new BufferedReader(isr);
String data = null;
while ((data = br.readLine())!=null){
// Print it using sysout, or do whatever you want with the incoming data from server
}
}
}
Server Side code
public class ServerTest {
ServerSocket s;
public void go() {
try {
s = new ServerSocket(44457);
while (true) {
Socket incoming = s.accept();
Thread t = new Thread(new MyCon(incoming));
t.start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
class MyCon implements Runnable {
Socket incoming;
public MyCon(Socket incoming) {
this.incoming = incoming;
}
#Override
public void run() {
try {
PrintWriter pw = new PrintWriter(incoming.getOutputStream(),
true);
InputStreamReader isr = new InputStreamReader(
incoming.getInputStream());
BufferedReader br = new BufferedReader(isr);
String inp = null;
boolean isDone = true;
System.out.println("TYPE : BYE");
System.out.println();
while (isDone && ((inp = br.readLine()) != null)) {
System.out.println(inp);
if (inp.trim().equals("BYE")) {
System.out
.println("THANKS FOR CONNECTING...Bye for now");
isDone = false;
s.close();
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
try {
s.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
e.printStackTrace();
}
}
}
public static void main(String[] args) {
new ServerTest().go();
}
}
Closing any input stream or output stream or reader or writer around a socket stream closes the socket, and by implication the other streams, readers, and writers.
Use the same streams, readers, writers for the life of the socket.

ServerSocket java-server reads input only once?

I have written a java server and here is the code:
try
{
ss = new ServerSocket(8080);
while (true)
{
socket = ss.accept();
System.out.println("Acess given");
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//out = new PrintWriter(socket.getOutputStream(),true);
line = in.readLine();
System.out.println("you input is :" + in.readLine());
}
}
And an iphone application is the client and there is the code for it:
- (void)viewDidLoad {
[super viewDidLoad];
socket = [[LXSocket alloc]init];
if ([socket connect:#"10.211.55.2" port:8080]) {
NSLog(#"socket has been created");
}
else {
NSLog(#"socket couldn't be created created");
}
#try {
}#catch (NSException * e) {
NSLog(#"Unable to send data");
}
[super viewDidLoad];
}
-(IBAction)sendData{
[socket sendString:#"A\n"];
}
I am having 2 problems here: first is that the server is only reading the input once. The second is that when ever I try to output the data it doesn't output until I have called the method twice (clicked on the uibutton twice). Not sure what is happening here. What am I doing wrong?
You are creating a new reader everytime in your while loop. Instead move the code outside the while loop and block on the readLine() call.
socket = ss.accept();
in = new BufferedReader(new InputStreamReader(socket.getInputStream());
String line = "";
while ( true) {
line = in.readLine();
System.out.println("you input is :" + line);
if ( "Bye".equals(line) )
break;
}
Here is an example server side program.
Since alphazero posted the pattern, I will post a brief stripped down implementation:
This is the Server:
try {
ServerSocket ss = new ServerSocket(portNumber);
logger.info("Server successfully started on port " + portNumber);
// infinite loop that waits for connections
while (true) {
SocketThread rst = new SocketThread(ss.accept());
rst.start();
}
} catch (IOException e) {
logger.info("Error: unable to bind to port " + portNumber);
System.exit(-1);
}
The SocketThread is something like:
public class SocketThread extends Thread {
private Socket communicationSocket = null;
public SocketThread(Socket clientSocket) {
communicationSocket = clientSocket;
try {
input = new ObjectInputStream(communicationSocket.getInputStream());
} catch (IOException e) {
logger.info("Error getting communication streams to transfer data.");
try {
communicationSocket.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
public void run() {
boolean listening=true;
DataObject command = null;
while (listening) {
try {
Object currentObject = input.readObject();
if (currentObject != null
&& currentObject instanceof DataObject) {
command = (DataObject) currentObject;
}
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} finally {
// If we got to this point is because we received a request from
// the client
// we can exit the loop
listening = false;
}
}
}
}
Note: "DataObject" is just a custom class which could be more practical since you can read the Dataobject itself from the socket without worrying about how many bytes you are reading, etc. Only condition is that DataObject is flagged as Serializable.
Hope it helps.
Tushar,
The general pattern is this (almost java but pseudo-code):
while (server-socket is accepting new connections)
{
// The server-socket's job is to listen for connection requests
// It does this typically in a loop (until you issue server-shutdown)
// on accept the server-socket returns a Socket to the newly connected client
//
socket s = server-socket.accept-connection();
// various options here:
//
// typically fire off a dedicated thread to servie this client
// but also review NIO or (home-grown) connection-map/handler patterns
// the general pattern:
// create a dedicated thread per connection accepted.
// pass Socket (s) to the handler method (a Runnable) and start it off
// and that is it.
// Here we use the general pattern and create a dedicated
// handler thread and pass of the new connections' socket reference
//
Thread handler-thread = new Thread (handler-routine-as-runnable, s);
handler-thread.start();
}

Categories