Server and multiple sockets

C

Chris

I'm a student, trying to write a server that can handle multiple
clients. It's closer to working than I was expecting but if I use
client 1, then client 2, client 1 then freezes. And then I can't close
the windows and have to stop the OS processes. The problem occurs with
this statement after port is defined:

ServerSocket ss = new ServerSocket(port);

which causes this message:

java.net.BindException: Address already in use: JVM_Bind

At that point no clients are running and nothing else has happened
with ports. I actually don't understand why the clients work at all,
since the socket doesn't seem to have been created successfully. After
the message above (and a trace), no other system messages appear
unless I try to close a window.

The following code includes comments using caps and ***, showing where
the trouble occurs. Any help greatly appreciated.

Chris
________________________________

package com.abc.server;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.net.*;
import java.io.*;

public class Server extends JPanel implements Runnable {
private static JTextArea serverLog;
private static int port;
private static Socket soc;
private static ObjectOutputStream oos;
private static ObjectInputStream ois;
private Thread internalThread;
private static PrintStream out;

public static void main(String[] args) {
JFrame f = new JFrame("Server");
f.setSize(600, 350);
f.setDefaultCloseOperation(f.EXIT_ON_CLOSE);
f.setVisible(true);
serverLog = new JTextArea();
f.add(serverLog);

out = new PrintStream(new TextAreaOutputStream(serverLog));
System.setOut(out);
System.setErr(out);

f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
try {
ois.close();
oos.flush();
oos.close();
soc.close();
} catch ( IOException ioe ) {
System.out.println(ioe + "\n");
ioe.printStackTrace();
}
System.exit(0);
}
});
port = 2001;
Server server = new Server();
System.out.println("Leaving main.");
}

public Server() {
internalThread = new Thread(this);
internalThread.start();
}

public void run() {
System.out.println("Server ready.");

int i = 1;
System.out.println("Start of ");
try {
System.out.println("Start of connecting section. i = " +
i);
// *** EXECUTES CORRECTLY TO HERE
ServerSocket ss = new ServerSocket(port);
// *** MESSAGE ISSUED HERE BUT SOCKET PARTIALLY WORKS
for ( ;; ) {
Socket sock = ss.accept();
System.out.println("Got connection #" + i);
ClientService cs = new ClientService(sock, i,
out);
i++ ;
}
} catch ( IOException ioe ) {
System.out.println(ioe + "\n");
ioe.printStackTrace();
}
// *** FOLLOWING PRINTS CORRECTLY BUT NO OTHER MESSAGES
System.out.println("Connection established.");
}
}


class ClientService implements Runnable {
private static ObjectOutputStream oos;
private static ObjectInputStream ois;
private Thread internalThread;
private Socket soc;
private int counter;

public ClientService(Socket s, int ctr, PrintStream outTxtArea) {
soc = s;
counter = ctr;
PrintStream out = outTxtArea;
System.setOut(out);
System.setErr(out);
internalThread = new Thread(this);
internalThread.start();
internalThread.interrupt();
}

public void run() {
System.out.println("Thread for client #" + counter);
try {
final InputStream is = soc.getInputStream();
oos = new ObjectOutputStream(soc.getOutputStream());
ois = new ObjectInputStream(is);
boolean done = false;
while ( !done ) {
String strFrmClnt = (String) ois.readObject();
String strToClnt = strFrmClnt.length() + " - " +
strFrmClnt;
if ( strFrmClnt == null ) {
done = true;
} else {
oos.writeObject(strToClnt);
}
}
ois.close();
oos.flush();
oos.close();
soc.close();
} catch ( ClassNotFoundException cnfe ) {
System.out.println(cnfe + "\n");
cnfe.printStackTrace();
} catch ( IOException ioe ) {
System.out.println(ioe + "\n");
ioe.printStackTrace();
}
}
}
 
S

SadRed

I'm a student, trying to write a server that can handle multiple
clients. It's closer to working than I was expecting but if I use
client 1, then client 2, client 1 then freezes. And then I can't close
the windows and have to stop the OS processes. The problem occurs with
this statement after port is defined:

ServerSocket ss = new ServerSocket(port);

which causes this message:

java.net.BindException: Address already in use: JVM_Bind

At that point no clients are running and nothing else has happened
with ports. I actually don't understand why the clients work at all,
since the socket doesn't seem to have been created successfully. After
the message above (and a trace), no other system messages appear
unless I try to close a window.

The following code includes comments using caps and ***, showing where
the trouble occurs. Any help greatly appreciated.

Chris
________________________________

package com.abc.server;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.net.*;
import java.io.*;

public class Server extends JPanel implements Runnable {
private static JTextArea serverLog;
private static int port;
private static Socket soc;
private static ObjectOutputStream oos;
private static ObjectInputStream ois;
private Thread internalThread;
private static PrintStream out;

public static void main(String[] args) {
JFrame f = new JFrame("Server");
f.setSize(600, 350);
f.setDefaultCloseOperation(f.EXIT_ON_CLOSE);
f.setVisible(true);
serverLog = new JTextArea();
f.add(serverLog);

out = new PrintStream(new TextAreaOutputStream(serverLog));
System.setOut(out);
System.setErr(out);

f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
try {
ois.close();
oos.flush();
oos.close();
soc.close();
} catch ( IOException ioe ) {
System.out.println(ioe + "\n");
ioe.printStackTrace();
}
System.exit(0);
}
});
port = 2001;
Server server = new Server();
System.out.println("Leaving main.");
}

public Server() {
internalThread = new Thread(this);
internalThread.start();
}

public void run() {
System.out.println("Server ready.");

int i = 1;
System.out.println("Start of ");
try {
System.out.println("Start of connecting section. i = " +
i);
// *** EXECUTES CORRECTLY TO HERE
ServerSocket ss = new ServerSocket(port);
// *** MESSAGE ISSUED HERE BUT SOCKET PARTIALLY WORKS
for ( ;; ) {
Socket sock = ss.accept();
System.out.println("Got connection #" + i);
ClientService cs = new ClientService(sock, i,
out);
i++ ;
}
} catch ( IOException ioe ) {
System.out.println(ioe + "\n");
ioe.printStackTrace();
}
// *** FOLLOWING PRINTS CORRECTLY BUT NO OTHER MESSAGES
System.out.println("Connection established.");
}

}

class ClientService implements Runnable {
private static ObjectOutputStream oos;
private static ObjectInputStream ois;
private Thread internalThread;
private Socket soc;
private int counter;

public ClientService(Socket s, int ctr, PrintStream outTxtArea) {
soc = s;
counter = ctr;
PrintStream out = outTxtArea;
System.setOut(out);
System.setErr(out);
internalThread = new Thread(this);
internalThread.start();
internalThread.interrupt();
}

public void run() {
System.out.println("Thread for client #" + counter);
try {
final InputStream is = soc.getInputStream();
oos = new ObjectOutputStream(soc.getOutputStream());
ois = new ObjectInputStream(is);
boolean done = false;
while ( !done ) {
String strFrmClnt = (String) ois.readObject();
String strToClnt = strFrmClnt.length() + " - " +
strFrmClnt;
if ( strFrmClnt == null ) {
done = true;
} else {
oos.writeObject(strToClnt);
}
}
ois.close();
oos.flush();
oos.close();
soc.close();
} catch ( ClassNotFoundException cnfe ) {
System.out.println(cnfe + "\n");
cnfe.printStackTrace();
} catch ( IOException ioe ) {
System.out.println(ioe + "\n");
ioe.printStackTrace();
}
}

}
if I use
client 1, then client 2
You are re-creating the same server socket each time
new client is created. Stop it and use one single server
socket for accepting multiple clients. Server does not
need to have run() method because one single Main
thread is enough for the server to run. Dispatch a
client handler thread for each accept()ed client.
 
K

Knute Johnson

Chris said:
I'm a student, trying to write a server that can handle multiple
clients. It's closer to working than I was expecting but if I use
client 1, then client 2, client 1 then freezes. And then I can't close
the windows and have to stop the OS processes. The problem occurs with
this statement after port is defined:

ServerSocket ss = new ServerSocket(port);

which causes this message:

java.net.BindException: Address already in use: JVM_Bind

At that point no clients are running and nothing else has happened
with ports. I actually don't understand why the clients work at all,
since the socket doesn't seem to have been created successfully. After
the message above (and a trace), no other system messages appear
unless I try to close a window.

The following code includes comments using caps and ***, showing where
the trouble occurs. Any help greatly appreciated.

Chris
________________________________

package com.abc.server;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.net.*;
import java.io.*;

public class Server extends JPanel implements Runnable {
private static JTextArea serverLog;
private static int port;
private static Socket soc;
private static ObjectOutputStream oos;
private static ObjectInputStream ois;
private Thread internalThread;
private static PrintStream out;

public static void main(String[] args) {
JFrame f = new JFrame("Server");
f.setSize(600, 350);
f.setDefaultCloseOperation(f.EXIT_ON_CLOSE);
f.setVisible(true);
serverLog = new JTextArea();
f.add(serverLog);

out = new PrintStream(new TextAreaOutputStream(serverLog));
System.setOut(out);
System.setErr(out);

f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
try {
ois.close();
oos.flush();
oos.close();
soc.close();
} catch ( IOException ioe ) {
System.out.println(ioe + "\n");
ioe.printStackTrace();
}
System.exit(0);
}
});
port = 2001;
Server server = new Server();
System.out.println("Leaving main.");
}

public Server() {
internalThread = new Thread(this);
internalThread.start();
}

public void run() {
System.out.println("Server ready.");

int i = 1;
System.out.println("Start of ");
try {
System.out.println("Start of connecting section. i = " +
i);
// *** EXECUTES CORRECTLY TO HERE
ServerSocket ss = new ServerSocket(port);
// *** MESSAGE ISSUED HERE BUT SOCKET PARTIALLY WORKS
for ( ;; ) {
Socket sock = ss.accept();
System.out.println("Got connection #" + i);
ClientService cs = new ClientService(sock, i,
out);
i++ ;
}
} catch ( IOException ioe ) {
System.out.println(ioe + "\n");
ioe.printStackTrace();
}
// *** FOLLOWING PRINTS CORRECTLY BUT NO OTHER MESSAGES
System.out.println("Connection established.");
}
}


class ClientService implements Runnable {
private static ObjectOutputStream oos;
private static ObjectInputStream ois;
private Thread internalThread;
private Socket soc;
private int counter;

public ClientService(Socket s, int ctr, PrintStream outTxtArea) {
soc = s;
counter = ctr;
PrintStream out = outTxtArea;
System.setOut(out);
System.setErr(out);
internalThread = new Thread(this);
internalThread.start();
internalThread.interrupt();
}

public void run() {
System.out.println("Thread for client #" + counter);
try {
final InputStream is = soc.getInputStream();
oos = new ObjectOutputStream(soc.getOutputStream());
ois = new ObjectInputStream(is);
boolean done = false;
while ( !done ) {
String strFrmClnt = (String) ois.readObject();
String strToClnt = strFrmClnt.length() + " - " +
strFrmClnt;
if ( strFrmClnt == null ) {
done = true;
} else {
oos.writeObject(strToClnt);
}
}
ois.close();
oos.flush();
oos.close();
soc.close();
} catch ( ClassNotFoundException cnfe ) {
System.out.println(cnfe + "\n");
cnfe.printStackTrace();
} catch ( IOException ioe ) {
System.out.println(ioe + "\n");
ioe.printStackTrace();
}
}
}

It looks to me like the server part should be working. The
BindException is caused by trying to open two sockets (server or
otherwise) on the same port. Could it be that you have two servers running?

There are a couple of odd things, one is why do you interrupt your
internalThread right after you create it in you client? I can't see any
reason for that but since you don't have any code that will throw an
InterruptedException in your client it really shouldn't cause you any
problem. Normally one wraps the server creation code in a permanent
loop in case it throws an exception. If you throw an exception in your
server it will stop.

I would rename the client code to something like server task as that is
closer to its function. The client is the code that talks to this code.

You are declaring ObjectInput/OutputStreams in both classes. You only
really need them in the task part of the code.

I just had a thought, are you trying to create two of these objects and
connecting them together?
 
C

Chris

I'm a student, trying to write a server that can handle multiple
clients. It's closer to working than I was expecting but if I use
client 1, then client 2, client 1 then freezes. And then I can't close
the windows and have to stop the OS processes. The problem occurs with
this statement after port is defined:
ServerSocket ss = new ServerSocket(port);
which causes this message:
java.net.BindException: Address already in use: JVM_Bind
At that point no clients are running and nothing else has happened
with ports. I actually don't understand why the clients work at all,
since the socket doesn't seem to have been created successfully. After
the message above (and a trace), no other system messages appear
unless I try to close a window.
The following code includes comments using caps and ***, showing where
the trouble occurs. Any help greatly appreciated.

package com.abc.server;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.net.*;
import java.io.*;
public class Server extends JPanel implements Runnable {
private static JTextArea serverLog;
private static int port;
private static Socket soc;
private static ObjectOutputStream oos;
private static ObjectInputStream ois;
private Thread internalThread;
private static PrintStream out;
public static void main(String[] args) {
JFrame f = new JFrame("Server");
f.setSize(600, 350);
f.setDefaultCloseOperation(f.EXIT_ON_CLOSE);
f.setVisible(true);
serverLog = new JTextArea();
f.add(serverLog);
out = new PrintStream(new TextAreaOutputStream(serverLog));
System.setOut(out);
System.setErr(out);
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
try {
ois.close();
oos.flush();
oos.close();
soc.close();
} catch ( IOException ioe ) {
System.out.println(ioe + "\n");
ioe.printStackTrace();
}
System.exit(0);
}
});
port = 2001;
Server server = new Server();
System.out.println("Leaving main.");
}
public Server() {
internalThread = new Thread(this);
internalThread.start();
}
public void run() {
System.out.println("Server ready.");
int i = 1;
System.out.println("Start of ");
try {
System.out.println("Start of connecting section. i = " +
i);
// *** EXECUTES CORRECTLY TO HERE
ServerSocket ss = new ServerSocket(port);
// *** MESSAGE ISSUED HERE BUT SOCKET PARTIALLY WORKS
for ( ;; ) {
Socket sock = ss.accept();
System.out.println("Got connection #" + i);
ClientService cs = new ClientService(sock, i,
out);
i++ ;
}
} catch ( IOException ioe ) {
System.out.println(ioe + "\n");
ioe.printStackTrace();
}
// *** FOLLOWING PRINTS CORRECTLY BUT NO OTHER MESSAGES
System.out.println("Connection established.");
}

class ClientService implements Runnable {
private static ObjectOutputStream oos;
private static ObjectInputStream ois;
private Thread internalThread;
private Socket soc;
private int counter;
public ClientService(Socket s, int ctr, PrintStream outTxtArea) {
soc = s;
counter = ctr;
PrintStream out = outTxtArea;
System.setOut(out);
System.setErr(out);
internalThread = new Thread(this);
internalThread.start();
internalThread.interrupt();
}
public void run() {
System.out.println("Thread for client #" + counter);
try {
final InputStream is = soc.getInputStream();
oos = new ObjectOutputStream(soc.getOutputStream());
ois = new ObjectInputStream(is);
boolean done = false;
while ( !done ) {
String strFrmClnt = (String) ois.readObject();
String strToClnt = strFrmClnt.length() + " - " +
strFrmClnt;
if ( strFrmClnt == null ) {
done = true;
} else {
oos.writeObject(strToClnt);
}
}
ois.close();
oos.flush();
oos.close();
soc.close();
} catch ( ClassNotFoundException cnfe ) {
System.out.println(cnfe + "\n");
cnfe.printStackTrace();
} catch ( IOException ioe ) {
System.out.println(ioe + "\n");
ioe.printStackTrace();
}
}
}
if I use
client 1, then client 2

You are re-creating the same server socket each time
new client is created. Stop it and use one single server
socket for accepting multiple clients. Server does not
need to have run() method because one single Main
thread is enough for the server to run. Dispatch a
client handler thread for each accept()ed client.

What I thought I had was just one server, which would create multiple
ClientService threads, so I thought the ServerSocket was created only
once. Can you say why the Server itself would be multiple? I should
have mentioned part of the assignment was for the server to be in a
self-running thread; that's why I have the run() method. Is there a
different way to use the method?

Anyway, I tried putting the server socket assignment in its own try-
catch but the result is similar. After the try-catch, the ServerSocket
is still null.

port = 2001;
ServerSocket ss = null;
try {
ss = new ServerSocket(port); \\ *** This fails
} catch ( IOException ioes ) {
System.out.println(ioes + "\n");
ioes.printStackTrace();
}

int i = 1;
try {
System.out.println("Start of socket defn.");
for ( ;; ) {
Socket sock = ss.accept();
System.out.println("Got connection #" + i);
ClientService cs = new ClientService(sock, i, out);
i++ ;
}
} catch ( IOException ioe ) {
System.out.println(ioe + "\n");
ioe.printStackTrace();
}
 
E

Esmond Pitt

SadRed said:
You are re-creating the same server socket each time
new client is created.

Absolute rubbish. He isn't.

Chris, your code is mostly fine except that you should always close
output streams of a socket before the input, and in fact once you've
done that closing the input stream or the socket is redundant. I also
don't know why you're starting the client thread and then immediately
interrupting it - don't do that.

Your problem is coming when restarting the server. Use new
ServerSocket(), then call serverSocket.setReuseAddress(), then
serverSocket.bind() to get around this.
 
C

Chris

Absolute rubbish. He isn't.

Chris, your code is mostly fine except that you should always close
output streams of a socket before the input, and in fact once you've
done that closing the input stream or the socket is redundant. I also
don't know why you're starting the client thread and then immediately
interrupting it - don't do that.

Your problem is coming when restarting the server. Use new
ServerSocket(), then call serverSocket.setReuseAddress(), then
serverSocket.bind() to get around this.

Does this apply even when I've just started the program? Because I get
an error on the first time. Also, since my "new ServerSocket"
statement is what causes the error, your other calls wouldn't affect
it if they came after it. One more question: I don't understand the
argument type for bind() -- it won't take the port number I'm using.
Thanks for your help.
 
C

Chris

Absolute rubbish. He isn't.

Chris, your code is mostly fine except that you should always close
output streams of a socket before the input, and in fact once you've
done that closing the input stream or the socket is redundant. I also
don't know why you're starting the client thread and then immediately
interrupting it - don't do that.

Your problem is coming when restarting the server. Use new
ServerSocket(), then call serverSocket.setReuseAddress(), then
serverSocket.bind() to get around this.

I tried to follow your suggestions, and I at least got rid of the bind
error, but I'm getting a NullPointerException. With the other code
pretty much the same (but declaring the ServerSocket at the top), the
problematic statement now has three new statements before it. Eclipse
accepts them, but the result still isn't right.

ss.setReuseAddress(true);
SocketAddress socAdr=ss.getLocalSocketAddress();
ss.bind(socAdr);
ss = new ServerSocket(port);
 
E

Esmond Pitt

Chris said:
ss.setReuseAddress(true);
SocketAddress socAdr=ss.getLocalSocketAddress();
ss.bind(socAdr);
ss = new ServerSocket(port);

Delete the last 3 lines and replace with

ss.bind(new InetSocketAddress(port));

If you get the BindException the first time you run it after a reboot,
someone else is already using the port, so you'll just have to use
another one.
 
K

Knute Johnson

Esmond said:
Chris, your code is mostly fine except that you should always close
output streams of a socket before the input, and in fact once you've
done that closing the input stream or the socket is redundant. I also
don't know why you're starting the client thread and then immediately
interrupting it - don't do that.

Actually I've found that you are better off closing the socket and
letting that close the streams. On occasion closing the streams can
hang the socket up. Less code too.
 
K

Knute Johnson

Chris said:
Does this apply even when I've just started the program? Because I get
an error on the first time. Also, since my "new ServerSocket"
statement is what causes the error, your other calls wouldn't affect
it if they came after it. One more question: I don't understand the
argument type for bind() -- it won't take the port number I'm using.
Thanks for your help.

What port are you using? Does some other program have that port
listening? Try netstat -a before your run your program to see what's
going on.
 
E

Esmond Pitt

Knute said:
Actually I've found that you are better off closing the socket and
letting that close the streams. On occasion closing the streams can
hang the socket up. Less code too.

But less data, too. The output stream doesn't get a chance to flush so
you will lose data. That's the only reason it can block (if the reader
is a way behind), but then of course it *should* block. Unless you like
truncated transmissions.
 
K

Knute Johnson

Esmond said:
But less data, too. The output stream doesn't get a chance to flush so
you will lose data. That's the only reason it can block (if the reader
is a way behind), but then of course it *should* block. Unless you like
truncated transmissions.

If you are not done reading why would you be closing the streams?

There is some sort of bug/feature/whatever under Winblows if the socket
on the server end throws an exception caused by the other end closing,
and you then attempt to close the streams on the server it can hang. It
shouldn't but it does occasionally. If you just close the socket that
doesn't happen.
 
C

Chris

I'm a student, trying to write a server that can handle multiple
clients. It's closer to working than I was expecting but if I use
client 1, then client 2, client 1 then freezes. And then I can't close
the windows and have to stop the OS processes. The problem occurs with
this statement after port is defined:

ServerSocket ss = new ServerSocket(port);

which causes this message:

java.net.BindException: Address already in use: JVM_Bind

At that point no clients are running and nothing else has happened
with ports. I actually don't understand why the clients work at all,
since the socket doesn't seem to have been created successfully. After
the message above (and a trace), no other system messages appear
unless I try to close a window.

The following code includes comments using caps and ***, showing where
the trouble occurs. Any help greatly appreciated.

Chris
________________________________

package com.abc.server;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.net.*;
import java.io.*;

public class Server extends JPanel implements Runnable {
private static JTextArea serverLog;
private static int port;
private static Socket soc;
private static ObjectOutputStream oos;
private static ObjectInputStream ois;
private Thread internalThread;
private static PrintStream out;

public static void main(String[] args) {
JFrame f = new JFrame("Server");
f.setSize(600, 350);
f.setDefaultCloseOperation(f.EXIT_ON_CLOSE);
f.setVisible(true);
serverLog = new JTextArea();
f.add(serverLog);

out = new PrintStream(new TextAreaOutputStream(serverLog));
System.setOut(out);
System.setErr(out);

f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
try {
ois.close();
oos.flush();
oos.close();
soc.close();
} catch ( IOException ioe ) {
System.out.println(ioe + "\n");
ioe.printStackTrace();
}
System.exit(0);
}
});
port = 2001;
Server server = new Server();
System.out.println("Leaving main.");
}

public Server() {
internalThread = new Thread(this);
internalThread.start();
}

public void run() {
System.out.println("Server ready.");

int i = 1;
System.out.println("Start of ");
try {
System.out.println("Start of connecting section. i = " +
i);
// *** EXECUTES CORRECTLY TO HERE
ServerSocket ss = new ServerSocket(port);
// *** MESSAGE ISSUED HERE BUT SOCKET PARTIALLY WORKS
for ( ;; ) {
Socket sock = ss.accept();
System.out.println("Got connection #" + i);
ClientService cs = new ClientService(sock, i,
out);
i++ ;
}
} catch ( IOException ioe ) {
System.out.println(ioe + "\n");
ioe.printStackTrace();
}
// *** FOLLOWING PRINTS CORRECTLY BUT NO OTHER MESSAGES
System.out.println("Connection established.");
}

}

class ClientService implements Runnable {
private static ObjectOutputStream oos;
private static ObjectInputStream ois;
private Thread internalThread;
private Socket soc;
private int counter;

public ClientService(Socket s, int ctr, PrintStream outTxtArea) {
soc = s;
counter = ctr;
PrintStream out = outTxtArea;
System.setOut(out);
System.setErr(out);
internalThread = new Thread(this);
internalThread.start();
internalThread.interrupt();
}

public void run() {
System.out.println("Thread for client #" + counter);
try {
final InputStream is = soc.getInputStream();
oos = new ObjectOutputStream(soc.getOutputStream());
ois = new ObjectInputStream(is);
boolean done = false;
while ( !done ) {
String strFrmClnt = (String) ois.readObject();
String strToClnt = strFrmClnt.length() + " - " +
strFrmClnt;
if ( strFrmClnt == null ) {
done = true;
} else {
oos.writeObject(strToClnt);
}
}
ois.close();
oos.flush();
oos.close();
soc.close();
} catch ( ClassNotFoundException cnfe ) {
System.out.println(cnfe + "\n");
cnfe.printStackTrace();
} catch ( IOException ioe ) {
System.out.println(ioe + "\n");
ioe.printStackTrace();
}
}



}- Hide quoted text -

- Show quoted text -

I received a number of responses with interesting suggestions but
someone in my company found the problem-- embarrassingly simple as
these things sometimes are. My input and output streams in the
ClientService class were declared static. So the conflict between the
client instances had to happen. (I guess I was sticking "static" on
things because Eclipse kept bugging me about variables.) Thanks to all
who looked over my code.
 
S

SadRed

I'm a student, trying to write a server that can handle multiple
clients. It's closer to working than I was expecting but if I use
client 1, then client 2, client 1 then freezes. And then I can't close
the windows and have to stop the OS processes. The problem occurs with
this statement after port is defined:
ServerSocket ss = new ServerSocket(port);
which causes this message:
java.net.BindException: Address already in use: JVM_Bind
At that point no clients are running and nothing else has happened
with ports. I actually don't understand why the clients work at all,
since the socket doesn't seem to have been created successfully. After
the message above (and a trace), no other system messages appear
unless I try to close a window.
The following code includes comments using caps and ***, showing where
the trouble occurs. Any help greatly appreciated.

package com.abc.server;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.net.*;
import java.io.*;
public class Server extends JPanel implements Runnable {
private static JTextArea serverLog;
private static int port;
private static Socket soc;
private static ObjectOutputStream oos;
private static ObjectInputStream ois;
private Thread internalThread;
private static PrintStream out;
public static void main(String[] args) {
JFrame f = new JFrame("Server");
f.setSize(600, 350);
f.setDefaultCloseOperation(f.EXIT_ON_CLOSE);
f.setVisible(true);
serverLog = new JTextArea();
f.add(serverLog);
out = new PrintStream(new TextAreaOutputStream(serverLog));
System.setOut(out);
System.setErr(out);
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
try {
ois.close();
oos.flush();
oos.close();
soc.close();
} catch ( IOException ioe ) {
System.out.println(ioe + "\n");
ioe.printStackTrace();
}
System.exit(0);
}
});
port = 2001;
Server server = new Server();
System.out.println("Leaving main.");
}
public Server() {
internalThread = new Thread(this);
internalThread.start();
}
public void run() {
System.out.println("Server ready.");
int i = 1;
System.out.println("Start of ");
try {
System.out.println("Start of connecting section. i = " +
i);
// *** EXECUTES CORRECTLY TO HERE
ServerSocket ss = new ServerSocket(port);
// *** MESSAGE ISSUED HERE BUT SOCKET PARTIALLY WORKS
for ( ;; ) {
Socket sock = ss.accept();
System.out.println("Got connection #" + i);
ClientService cs = new ClientService(sock, i,
out);
i++ ;
}
} catch ( IOException ioe ) {
System.out.println(ioe + "\n");
ioe.printStackTrace();
}
// *** FOLLOWING PRINTS CORRECTLY BUT NO OTHER MESSAGES
System.out.println("Connection established.");
}

class ClientService implements Runnable {
private static ObjectOutputStream oos;
private static ObjectInputStream ois;
private Thread internalThread;
private Socket soc;
private int counter;
public ClientService(Socket s, int ctr, PrintStream outTxtArea) {
soc = s;
counter = ctr;
PrintStream out = outTxtArea;
System.setOut(out);
System.setErr(out);
internalThread = new Thread(this);
internalThread.start();
internalThread.interrupt();
}
public void run() {
System.out.println("Thread for client #" + counter);
try {
final InputStream is = soc.getInputStream();
oos = new ObjectOutputStream(soc.getOutputStream());
ois = new ObjectInputStream(is);
boolean done = false;
while ( !done ) {
String strFrmClnt = (String) ois.readObject();
String strToClnt = strFrmClnt.length() + " - " +
strFrmClnt;
if ( strFrmClnt == null ) {
done = true;
} else {
oos.writeObject(strToClnt);
}
}
ois.close();
oos.flush();
oos.close();
soc.close();
} catch ( ClassNotFoundException cnfe ) {
System.out.println(cnfe + "\n");
cnfe.printStackTrace();
} catch ( IOException ioe ) {
System.out.println(ioe + "\n");
ioe.printStackTrace();
}
}
}- Hide quoted text -
- Show quoted text -

I received a number of responses with interesting suggestions but
someone in my company found the problem-- embarrassingly simple as
these things sometimes are. My input and output streams in the
ClientService class were declared static. So the conflict between the
client instances had to happen. (I guess I was sticking "static" on
things because Eclipse kept bugging me about variables.) Thanks to all
who looked over my code.

Awfull. Your Server class also has a few static fields. We had
taken for granted that there can't be such code in c/s program.
But there were!
 
E

Esmond Pitt

Knute said:
If you are not done reading why would you be closing the streams?

Maybe I didn't make myself clear. If you try to close a buffered stream
and the *other* end is far enough behind in its reading, the flush()
implied by the close() will block, and this is surely the desired action.
There is some sort of bug/feature/whatever under Winblows if the socket
on the server end throws an exception caused by the other end closing,
and you then attempt to close the streams on the server it can hang. It
shouldn't but it does occasionally. If you just close the socket that
doesn't happen.

Never seen or heard of it myself, but if you close in response to an
exception (other than EOFException) you should of course take the
shortest way home, which is certainly just to close the socket.
 
K

Knute Johnson

Esmond said:
Maybe I didn't make myself clear. If you try to close a buffered stream
and the *other* end is far enough behind in its reading, the flush()
implied by the close() will block, and this is surely the desired action.

I'm with you there.
Never seen or heard of it myself, but if you close in response to an
exception (other than EOFException) you should of course take the
shortest way home, which is certainly just to close the socket.

That's what I think.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top