Consider the following Server:
public class TestServer {
public static void main(String[] args) {
String ksName = "/some/path/keystore-server.jks";
char ksPass[] = "password".toCharArray();
char ctPass[] = "pswd".toCharArray();
KeyStore ks;
try {
ks = KeyStore.getInstance("JKS");
ks.load(new FileInputStream(ksName), ksPass);
KeyManagerFactory kmf =
KeyManagerFactory.getInstance("SunX509");
kmf.init(ks, ctPass);
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(kmf.getKeyManagers(), null, null);
SSLServerSocketFactory ssf = sc.getServerSocketFactory();
SSLServerSocket s = (SSLServerSocket) ssf.createServerSocket(SERVER_PORT);
while(true){
SSLSocket sslsocket = (SSLSocket) s.accept();
System.out.println("New Client accepted");
TestThread t = new TestThread(sslsocket);
t.run();
}
} catch (KeyStoreException | IOException | NoSuchAlgorithmException | CertificateException | UnrecoverableKeyException | KeyManagementException ex) {
Logger.getLogger(TotalControlServer.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
The above is a simple server that accepts several clients: right after accepting a new connection, a dispatch a new thread (TestThread) in order to deal with the client incoming requests. Here's the code for TestThread:
public class TestThread implements Runnable {
SSLSocket sslsocket;
public TestThread(SSLSocket sslsocket) {
this.sslsocket = sslsocket;
}
#Override
public void run() {
ObjectInputStream is = null;
ObjectOutputStream os = null;
try {
is = new ObjectInputStream(sslsocket.getInputStream());
os = new ObjectOutputStream(sslsocket.getOutputStream());
while(true){
String p = (String) is.readObject();
System.out.println("We got: " + p);
os.writeObject(p.concat(p));
os.flush();
}//while
} catch (IOException ex) {
Logger.getLogger(CmdLineService.class.getName()).log(Level.SEVERE, null, ex);
} catch (ClassNotFoundException ex) {
Logger.getLogger(CmdLineService.class.getName()).log(Level.SEVERE, null, ex);
} finally {
try {
is.close();
os.close();
this.sslsocket.close();
} catch (IOException ex) {
Logger.getLogger(CmdLineService.class.getName()).log(Level.SEVERE, null, ex);
}
}
}//run
}
Simple enough, it just loops indefinitely reading Strings and sending back its concatenation with itself.
The client is also rather simple:
public class TestClient {
public static void main(String[] args) {
System.setProperty("javax.net.ssl.trustStore" , "/path/keystore-client.jks") ;
ObjectOutputStream os = null;
ObjectInputStream is = null;
SSLSocket sslsocket = null;
try {
SSLSocketFactory f = (SSLSocketFactory) SSLSocketFactory.getDefault();
sslsocket = (SSLSocket) f.createSocket("localhost", SERVER_PORT);
sslsocket.startHandshake();
System.out.println("Authentication done");
os = new ObjectOutputStream(sslsocket.getOutputStream());
is = new ObjectInputStream(sslsocket.getInputStream());
BufferedReader b = new BufferedReader(new InputStreamReader(System.in));
boolean exit = false;
while(!exit){
System.out.print("> ");
String line = b.readLine();
os.writeObject(line);
os.flush();
String s = (String) is.readObject();
System.out.println(s);
}//while
} //main
catch (IOException ex) {
Logger.getLogger(TotalControlCmdClient.class.getName()).log(Level.SEVERE, null, ex);
} catch (ClassNotFoundException ex) {
Logger.getLogger(TestClient.class.getName()).log(Level.SEVERE, null, ex);
} finally {
try {
is.close();
sslsocket.close();
} catch (IOException ex) {
Logger.getLogger(TestClient.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
Just loops indefinitely sending strings and reading a string.
This works fine for one client.. However, if I start another client, it does not connect! It seems that I'm facing some kind of thread starvation issue..
How can I fix that?
The reason is simple: You never start a second listener Thread:
while(true){
SSLSocket sslsocket = (SSLSocket) s.accept();
System.out.println("New Client accepted");
TestThread t = new TestThread(sslsocket);
t.run();
}
Calling run() does not start the Thread, that is done using start().
Therefore the main thread is processing the content of the run() method and as it is busy you can not connect using a second client.
Change t.run() to t.start and everything will be fine.
Related
Hello i'm trying to run a SSL server and client program. I'm first creating a certificate with the cmd command "keytool -genkey -keystore mySrvKeyStore -keyalg RSA". 123456 is the password after i fill in the info. I put the certificate in the same folder as the server and client, i run the server and I get this error:
"java.lang.IllegalStateException: SSLContext is not initialized"
The server:
public class SSLServer {
private static int port = 4000;
private static SSLServerSocketFactory sf;
private static SSLServerSocket ss;
public static void StabilireConexiune(int nrPort) {
try {
sf = (SSLServerSocketFactory) SSLServer.getServerSocketFactory();
ss = (SSLServerSocket) sf.createServerSocket(nrPort);
System.out.println("Server connected ready to accept new connections at the address " + ss.getLocalPort());
String[] enable = {"TLS_DH_anon_WITH_AES_128_CBC_SHA"};
ss.setEnabledCipherSuites(enable);
String[] cipherSuites = ss.getEnabledCipherSuites();
System.out.println("CipherSuites: ");
for (int i = 0; i < cipherSuites.length; i++) {
System.out.println(cipherSuites[i]);
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
private static SSLSocket clientSocket;
public static void ConectareClient(){
try{
clientSocket = (SSLSocket) ss.accept();
System.out.println("Client connected succesfully");
InputStream input = clientSocket.getInputStream();
InputStreamReader inputreader = new InputStreamReader(input);
BufferedReader br = new BufferedReader(inputreader);
String string = null;
while( (string = br.readLine()) != null){
System.out.println(string);
System.out.flush();
}
}catch(Exception ex){
ex.printStackTrace();
}
finally{
try{
clientSocket.close();
}catch(IOException ex){
ex.printStackTrace();
}
}
}
private static ServerSocketFactory getServerSocketFactory() throws NoSuchAlgorithmException{
SSLServerSocketFactory ssf = null;
try{
KeyManagerFactory kmf;
KeyStore ks;
SSLContext ctx;
char[] passphrase = "123456".toCharArray();
ctx = SSLContext.getInstance("TLS");
kmf = KeyManagerFactory.getInstance("SunX509");
ks = KeyStore.getInstance("JKS");
ks.load(new FileInputStream("mySrvKeystore"), passphrase);
kmf.init(ks, passphrase);
ctx.getServerSocketFactory();
return ssf;
}catch(Exception ex){
ex.printStackTrace();
}
return null;
}
public static void main(String args[]){
if(args.length != 0){
port = Integer.parseInt(args[0]);
}
StabilireConexiune(port);
while(true){
ConectareClient();
}
}}
The client:
public class SSLClient {
public static void main(String args[]) {
conectare("127.0.0.1", 4000);
}
private static SSLSocket socket;
public static void conectare(String host, int port) {
try {
SSLSocketFactory factory = (SSLSocketFactory) SSLClient.getSocketFactory();
socket = (SSLSocket) factory.createSocket(host, port);
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] enable = {"TLS_DH_anon_WITH_AES_128_CBC_SHA"};
socket.setEnabledCipherSuites(enable);
String[] cipherSuites = socket.getEnabledCipherSuites();
for (int i = 0; i < cipherSuites.length; i++) {
System.out.println(cipherSuites[i]);
}
socket.addHandshakeCompletedListener(new HandshakeCompletedListener() {
public void handshakeCompleted(HandshakeCompletedEvent event) {
System.out.println("handshake done");
}
});
socket.startHandshake();
PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())));
System.out.println("Give a message to the server...");
String string = br.readLine();
out.println("Message to the server..." + string);
out.println();
out.flush();
}catch(IOException ex){
ex.printStackTrace();
}
finally{
try{
socket.close();
}catch(IOException ex){
ex.printStackTrace();
}
}
}
private static SocketFactory getSocketFactory(){
SSLSocketFactory ssf = null;
try{
SSLContext ctx;
KeyManagerFactory kmf;
KeyStore ks;
char[] passphrase = "123456".toCharArray();
ctx = SSLContext.getInstance("TLS");
kmf = KeyManagerFactory.getInstance("SunX509");
ks = KeyStore.getInstance("JKS");
ks.load(new FileInputStream("mySrvKeystore"), passphrase);
kmf.init(ks, passphrase);
ctx.init(kmf.getKeyManagers(), null, null);
ssf = ctx.getSocketFactory();
return ssf;
}catch(Exception e){
e.printStackTrace();
}
return null;
}}
Please help me, what is the problem?
The error is in these two lines:
SSLContext ctx = SSLContext.getInstance("TLS");
ctx.getServerSocketFactory();
Why does it throw this Exception? Method getServerSocketFactory() states:
Throws:
IllegalStateException - if the SSLContextImpl requires initialization and the init() has not been called
In the client, you do indeed call ctx.init(kmf.getKeyManagers(), null, null); before you call ctx.getServerSocketFactory();
But in the server you do not call this - you only initialise the KeyManagerFactory.
I'm trying to connect to java server socket placed on windows server from my computer.
I always got a timeout exception.
I have tried to disable firewall with no luck. it still gave me the same error.
Exception in thread "main" java.net.ConnectException: Connection timed out: connect
at java.net.DualStackPlainSocketImpl.connect0(Native Method)
server code
public class Server implements Runnable {
public static int PORT = 3425;
private ServerSocket server;
public Server() throws IOException{
server = new ServerSocket(PORT);
}
#Override
public void run() {
try {
System.out.println("Waiting for connection");
Socket socket = server.accept();
System.out.println("new socket attached " + socket.toString());
System.out.println("waiting for message to read it");
DataInputStream input = new DataInputStream(socket.getInputStream());
byte [] bytes = new byte[1000];
int text = input.read(bytes);
System.out.println("message received");
System.out.println(text);
System.out.println(Arrays.toString(bytes));
} catch (IOException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
Client Code
public class Client implements Runnable {
Socket socket;
public Client() throws IOException {
System.out.println("trying to connect");
socket = new Socket("74.208.80.229", Server.PORT);
System.out.println("connected");
}
#Override
public void run() {
try {
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
Thread.sleep(1000);
System.out.println("message sent");
out.writeUTF("kasjdlkahdklajhdlkajsdhakljsdhlk");
out.flush();
} catch (IOException ex) {
Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
} catch (InterruptedException ex) {
Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
I am working on Socket programming. I have build such a server which should accept multiple Clients. Here I have particular num of clients , clients keeps on sending msg to Server every 10sec , Server has to process it.The problem I am having is I am unable to connect multiple Server and here a single client is a continuous running programm in while(true) So if one client Sends a request another client can not connect . Here is my Program.
Server
public class SimpleServer extends Thread {
private ServerSocket serverSocket = null;
private Socket s1 = null;
SimpleServer() {
try {
serverSocket = new ServerSocket(1231);
this.start();
} catch (IOException ex) {
System.out.println("Exception on new ServerSocket: " + ex);
}
}
public void run() {
while (true) {
try {
System.out.println("Waiting for connect to client");
s1 = serverSocket.accept();
System.out.println("Connection received from " + s1.getInetAddress().getHostName());
InputStream s1In = s1.getInputStream();
DataInputStream dis = new DataInputStream(s1In);
String st = dis.readUTF();
System.out.println(st);
s1In.close();
dis.close();
s1.close();
// throw new ArithmeticException();
} catch (IOException ex) {
Logger.getLogger(SimpleServer.class.getName()).log(Level.SEVERE, null, ex);
}
catch (Exception e) {
System.out.println("Exceptiopn: "+e);
}
}
}
public static void main(String args[]) throws IOException {
new SimpleServer();
}
}
Server is working fine but I am not able to write Client program which shoud run in while(true) loop for sending msg to Server and allow other client also connect to Server.
but for a single client I write like this ,
public class SimClient extends Thread {
private Socket s1 = null;
SimClient() {
//this.start();
}
public void run() {
int i=0;
try {
s1 = new Socket("localhost", 1231);
} catch (IOException ex) {
Logger.getLogger(SimClient.class.getName()).log(Level.SEVERE, null, ex);
}
// while (i<10) {
try {
// Open your connection to a server, at port dfg1231
OutputStream s1out = s1.getOutputStream();
DataOutputStream dos = new DataOutputStream(s1out);
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Enter Data from Client:");
String s = br.readLine();
dos.writeUTF(s);
dos.flush();
s1out.close();
dos.close();
// s1.close();
i++;
} catch (IOException ex) {
//ex.printStackTrace();
System.out.println("Exception in While: "+ex.getMessage());
}
//}
}
public static void main(String args[]) throws IOException {
SimClient s= new SimClient();
s.start();
}
}
So can any one help me to write client program. its a great help for me.
just as you have a Thread for the ServerSocket, you need to create a Thread for every Socket returned by serverSocket.accept() , then it loops back around immediately to block and wait to accept another Socket. Make a class called SocketHander which extends Thread and accepts a Socket in the constructor.
public class SocketHandler extends Thread {
private Socket socket;
public SocketHandler(Socket socket) {
this.socket = socket;
}
public void run() {
// use the socket here
}
}
and back in the ServerSocket handler...
for (;;) {
SocketHandler socketHander = new SocketHandler(serverSocket.accept());
socketHander.start();
}
It is generally a good idea to use a Fixed Size Thread Pool because creating Threads in a ad-hoc manner may cause the Server to run out of Threads if the requests are high.
public class SimpleServer extends Thread {
private ServerSocket serverSocket = null;
private static ExecutorService executor = Executors.newFixedThreadPool(100);
SimpleServer() {
try {
serverSocket = new ServerSocket(1231);
this.start();
} catch (IOException ex) {
System.out.println("Exception on new ServerSocket: " + ex);
}
}
public void run() {
while (true) {
try {
System.out.println("Waiting for connect to client");
final Socket s1 = serverSocket.accept();
executor.execute(new Runnable() {
public void run() {
try {
System.out.println("Connection received from " + s1.getInetAddress().getHostName());
InputStream s1In = s1.getInputStream();
DataInputStream dis = new DataInputStream(s1In);
String st = dis.readUTF();
System.out.println(st);
s1In.close();
dis.close();
s1.close();
} catch(Exception e) {
System.out.println("Exceptiopn: "+e);
}
// throw new ArithmeticException();
}});
} catch (IOException ex) {
Logger.getLogger(SimpleServer.class.getName()).log(Level.SEVERE, null, ex);
} catch (Exception e) {
System.out.println("Exceptiopn: "+e);
}
}
}
public static void main(String args[]) throws IOException {
new SimpleServer();
}
}
I am new to google protocol buffer . I am writing a client server application where client send request object to server and server return response. Currently when i send object to server neither the server respond nor throw any exception. Probably it stuck on line
Request request = Request.parseFrom(bytes);
where Request and Response are my message classes generated by protocol buffer.
My code samples are as follows
public class TCPServer {
final static Logger logger = Logger.getLogger(TCPServer.class.getName());
static int PORT = 6789;
public static void main(String argv[]) throws Exception
{
ServerSocket socket = new ServerSocket(PORT);
Socket connectionSocket = null;
while(true)
{
try{
connectionSocket = socket.accept();
}catch (IOException e) {
System.out.println("Could not listen on port:" + PORT);
System.exit(-1);
}
Thread thread = new Thread(new ServerConnection(connectionSocket));
thread.start();
}
}
}
public class ServerConnection implements Runnable{
static final Logger logger = Logger.getLogger(ServerConnection.class.getName());
String clientInput;
String serverOutput = null;
Socket connectionSocket = null;
ServerConnection(Socket connectionSocket){
this.connectionSocket = connectionSocket;
}
public void run() {
try {
InputStream input = connectionSocket.getInputStream();
ObjectInputStream inFromClient = new ObjectInputStream(input);
ObjectOutputStream outToClient = new ObjectOutputStream(connectionSocket.getOutputStream());
serveRequest(inFromClient , outToClient);
outToClient.flush();
} catch (IOException ex) {
logger.log(Level.SEVERE, null, ex);
System.out.println("Exception occured in ServerConnection run() method");
}
}
public void serveRequest(InputStream inFromClient, OutputStream outToClient){
try {
System.out.println("Recieving data from client");
ResponseReciever response = new ResponseReciever();
ObjectInputStream input = (ObjectInputStream) inFromClient;
byte size = input.readByte();
byte []bytes = new byte[size];
input.readFully(bytes);
Request request = Request.parseFrom(bytes);
System.out.println("Request recieved");
response.createResponse(request.getId(),request.getMessage(),true).writeTo(outToClient);
System.out.println("Response send");
} catch (Exception ex) {
logger.log(Level.SEVERE, null, ex);
System.out.println("Exception occured in ServerConnection serverRequest() method");
}
}
And my client look like this
public class TCPClient {
final static Logger logger = Logger.getLogger(TCPClient.class.getName());
private static int PORT = 6789;
private static String HOST_NAME = "localhost";
private static boolean isOpen = true;
private Socket openConnection(final String hostName,final int port){
Socket clientSocket = null;
try {
clientSocket = new Socket(HOST_NAME, PORT);
} catch (IOException e) {
logger.log(Level.SEVERE, "Exception occured while connecting to server", e);
}
return clientSocket;
}
private void closeConnection(Socket clientSocket){
try {
logger.log(Level.INFO, "Closing the connection");
clientSocket.close();
isOpen = false;
} catch (IOException e) {
logger.log(Level.SEVERE, "Exception occured while closing the connection", e);
}
}
public void sendToServer(OutputStream output){
try {
System.out.println("Sending data to server");
RequestSender requestSender = new RequestSender();
Request request = requestSender.getRequest(1,"param1","param2",23L,"Its message",true);
ObjectOutputStream outputStream = (ObjectOutputStream)output;
request.writeTo(outputStream);
} catch (IOException ex) {
logger.log(Level.SEVERE, null, ex);
}
}
public void recieveFromServer(InputStream input){
try {
System.out.println("Recieving data from server");
Response response = Response.parseFrom(input);
System.out.println(response.getId());
System.out.println(response.getResponse());
System.out.println(response.getError());
} catch (IOException ex) {
logger.log(Level.SEVERE, null, ex);
}
}
public static void main(String argv[]) throws Exception
{
ObjectOutputStream outToServer = null;
InputStream inFromServer = null;
TCPClient client = new TCPClient();
try {
while(isOpen)
{
Socket clientSocket = client.openConnection(HOST_NAME, PORT);
outToServer = new ObjectOutputStream(clientSocket.getOutputStream());
inFromServer = new ObjectInputStream(clientSocket.getInputStream());
client.sendToServer(outToServer);
client.recieveFromServer(inFromServer);
}
}catch (Exception e) {
logger.log(Level.SEVERE, "Exception occured ", e);
System.out.println("Exception occured in TCPClient main() method");
System.exit(1);
}
}
}
I am unable to find what is wrong in the code. Please let me know if you find something missing.
It works by using writeDelimtedTo(outputStream) and parseDelimitedFrom(inputStream) instead of writeTo(outputStream) and parseFrom(inputStream). So by putting the following code on server and client sides the program works.
Server side:
InputStream input = connectionSocket.getInputStream();
OutputStream output = connectionSocket.getOutputStream();
Request request = null;
while ((request = Request.parseDelimitedFrom(input)) != null) {
System.out.println(request.toString());
}
Client side:
Socket clientSocket = client.openConnection(HOST_NAME, PORT);
Request request = getRequest();
OutputStream output = clientSocket.getOutputStream();
InputStream input = clientSocket.getInputStream();
request.writeDelimitedTo(output);
If you start sending protocol buffers over the wire - then you will need to "frame" them. The problem is reported and solved with this question: does protobuf need a network packet header?
Instead of writing all this code, you could checkout https://code.google.com/p/protobuf-rpc-pro/ and see if it satisfies your requirements for RPC between java server and java clients.
I have a problem with my Java program. It has a socket connection between a server and many client. Here is the server (the part which concerns the problem):
private static ArrayList<ParallelServer> clientConnected = new ArrayList<ParallelServer>();
public Server(int port) {
this.port = port;
if (!startServer())
JOptionPane.showMessageDialog(new JFrame(""),
"Error!", "ERROR!",
JOptionPane.ERROR_MESSAGE);
}
private boolean startServer() {
try {
server = new ServerSocket(port);
loadDatabase();
} catch (IOException ex) {
ex.printStackTrace();
return false;
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return true;
}
public void runServer() {
while (true) {
try {
client = server.accept();
ParallelServer pServer = new ParallelServer(client);
clientConnected.add(pServer);
Thread thread = new Thread(pServer);
thread.start();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
public static void sendBroadcast(String username) throws IOException {
for(int i = 0; i < clientConnected.size(); i++)
clientConnected.get(i).sendAnswer("#change," + username);
}
The parallel server is:
private Socket client;
private InputStreamReader inputstreamreader;
private BufferedReader bufferedreader;
private PrintWriter printwriter;
public ParallelServer(Socket client) {
this.client = client;
}
public void run() {
try {
inputstreamreader = new InputStreamReader(client.getInputStream());
bufferedreader = new BufferedReader(inputstreamreader);
printwriter = new PrintWriter(client.getOutputStream(), true);
String lineread = "";
while (client.isConnected()) {
lineread = bufferedreader.readLine();
doCommand(lineread);
}
} catch (UnknownHostException unhe) {
} catch (InterruptedIOException intioe) {
} catch (IOException ioe) {
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public void sendAnswer(String answer) throws IOException {
printwriter = new PrintWriter(client.getOutputStream(), true);
printwriter.println(answer);
printwriter.flush();
}
And here is the client:
private String serverurl = "localhost";
private int serverport = 7777;
private PrintWriter printwriter;
private InputStreamReader inputstreamreader;
private BufferedReader bufferedreader;
private Socket server;
public Client() {
server = null;
try {
server = new Socket(serverurl, serverport);
server.setSoTimeout(5000);
} catch (UnknownHostException unhe) {
System.out.println("UnknownHostException: " + unhe.getMessage());
} catch (InterruptedIOException intioe) {
System.out.println("Timeout while attempting to establish socket connection.");
} catch (IOException ioe) {
JOptionPane.showMessageDialog(new JFrame(),"Unable to reach the server!","ERROE!",JOptionPane.ERROR_MESSAGE);
}
}
public String sendCommand(String command) throws IOException {
if(server == null) {
try {
server = new Socket(serverurl, serverport);
server.setSoTimeout(5000);
} catch (UnknownHostException unhe) {
System.out.println("UnknownHostException: " + unhe.getMessage());
} catch (InterruptedIOException intioe) {
System.out.println("Timeout while attempting to establish socket connection.");
} catch (IOException ioe) {
JOptionPane.showMessageDialog(new JFrame(),"Unable to reach the server!","ERROR!",JOptionPane.ERROR_MESSAGE);
}
}
if(server != null) {
printwriter = new PrintWriter(server.getOutputStream(), true);
printwriter.println(command);
printwriter.flush();
inputstreamreader = new InputStreamReader(server.getInputStream());
bufferedreader = new BufferedReader(inputstreamreader);
return bufferedreader.readLine();
}
else
return "#serverProblem";
}
The program is a simple online game with turns. Players' turns are created with a queue and when a player passes his turn, the server send a broadcast message which say "Now it is 'Player 1' turn." (for instance). My problem is that when a client receive the message, its like it add the answer "Now it is 'Player 1' turn." to the next message it will receive. In my case: when a player passes his turn, he sends "#passTurn,username". The ParallelServer class polls it from the queue, puts it at the bottom of the queue, sends the client "#ok" to tell it that the turn has changed successfully and tells the Server class to send the broadcast message. Then, when the same client will try do do a further action, it will consider "Now it is 'Player 1' turn." as the answer the server has given to it. Instead, I would like that the server and the clients work as always and when the broadcast message is cought, the client is notified without any collateral effect.
What can I do?
Thanks.
Your bi-directional message passing mechanism should look something like this:
Server:
Wait on any client InputStream
if (broadcast)
broadcast_message()
else
process_message()
Client:
Receiving Thread:
Wait on server broadcast
Sending Thread:
Wait on messages to be sent to server from the User Input
This should do the trick :)
Hope it helps. Cheers!