We help IT Professionals succeed at work.

We've partnered with Certified Experts, Carl Webster and Richard Faulkner, to bring you two Citrix podcasts. Learn about 2020 trends and get answers to your biggest Citrix questions!Listen Now

x

pls help to correct my echo server

ikhmer
ikhmer asked
on
Medium Priority
236 Views
Last Modified: 2011-10-03
Dear Expert,

I want below code to get input command from client and execute in upper server then return result back to client! pls have a look at line 87 and help to correct me!
while i'm run this code the loop in line 90 is never finished!

this application will act as middleware ===> (Upper Svr <=> "This application" <=> Client)

====code ====

import java.net.*;
import java.io.*;

public class _13PoolEchoServer extends Thread {
  /** variable for UPPER SERVER side **/

  public static Socket upServer;
  public static PrintWriter outS;
  public static BufferedReader inS;      
 
  public static String upper_out;

   
         
  /** variable for client side  **/
  public final static int defaultPort = 2347;
  ServerSocket theServer;
  static int numberOfThreads = 10;    
 
 
   //contructor: for client connection -->act as server
   public _13PoolEchoServer(ServerSocket ss) {
         theServer = ss;
   }             
 
    public static void main(String[] args) {        
 
        
    int port = defaultPort;
    String iCmd = "LOGIN:USER,PWD:P@SSW@RD;";    
   
    try {
      port = Integer.parseInt(args[0]);
    }
    catch (Exception ex) {
          System.err.println(ex);
    }
    if (port <= 0 || port >= 65536) port = defaultPort;
   
    try {
      ServerSocket ss = new ServerSocket(port);
      for (int i = 0; i < numberOfThreads; i++) {            
            System.out.println("Starting thread : " + i);
        _13PoolEchoServer pes = new _13PoolEchoServer(ss);        
        pes.start();
      }
    }
    catch (IOException ex) {
      System.err.println(ex);      
    }

    try{    
        upServer = new Socket("192.168.0.5",4444);
        outS = new PrintWriter(upServer.getOutputStream(),true);
        inS  = new BufferedReader(new InputStreamReader(upServer.getInputStream()),1024);
        
        if(upServer.isConnected()) {                              
               outS.println("LOGIN:USER,PWD:P@SSW@RD;");        
              System.out.println("Server is connected to Upper Servers ");               
         }  
              
        
        while ((upper_out = inS.readLine()) != null) {                                  
          System.out.println("From UPPER SERVER: " + upper_out);         
      }
        
   }
   catch (IOException ex) {
      System.err.println(ex);    
   }      
 }       
 
  public void run() {
 
    while (true) {
      try {
        Socket s = theServer.accept();        
        System.out.println("Client request is accepted!!!");                      
        PrintWriter out = new PrintWriter(s.getOutputStream(), true);              
        BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()), 1024 );  
        while (true) {                
                String n = in.readLine();
         
                if (n == null) break;    
                System.out.println("Client said: " + n );
                
                //send and read from Svr  #??????????????????? HOW CAN I GET DATA FROM CLIENT AND SEND TO UPPERSER THEN RETURN THE RESULT BACK TO CLIENT  ??????
                outS.println(n);
                System.out.println(n + " were sent to Upper server");
                while ((upper_out = inS.readLine()) != null) {                                  
                      System.out.println("From UPPER SERVER: " + upper_out);         
              }
              System.out.println("From UPPER SERVER: " + inS.readLine());
                //end
                  
                out.println(n);
                out.flush();          
         
        } // end while        
       } // end try
      catch (IOException ex) {
            System.err.println(ex);
      }      
    } // end while
  } // end run    
}
Comment
Watch Question

Mick BarryJava Developer
CERTIFIED EXPERT
Top Expert 2010

Commented:
if you're upper server is closing the connection once its done then you will need to open the connection *inside* the loop.

Author

Commented:
the connection is not closed! and i believe it send the command from client to upper already-- the problem is how can i get result from uper server back!

Author

Commented:
it may related to line 63 because it perform the same job! when i turn off
        while ((upper_out = inS.readLine()) != null) {                                  
          System.out.println("From UPPER SERVER: " + upper_out);         
      }
in line 63,64,65 from client it can receive the result but i got the result of login command in line 58 instead of request command from client!

why? how to solve this?

thanks,
Mick BarryJava Developer
CERTIFIED EXPERT
Top Expert 2010

Commented:
if the connection is not closed then the upper server needs to send some indication that it has finished sending results

>        while ((upper_out = inS.readLine()) != null) {                              

readLine() won't be null until connection closed.
CERTIFIED EXPERT
Top Expert 2016

Commented:
Just have the class read the stream in its run method and send the result directly back to the client. Having an 'upper server' is unnecessary
try flushing here:

                    //send and read from Svr  #??????????????????? HOW CAN I GET DATA FROM CLIENT AND SEND TO UPPERSER THEN RETURN THE RESULT BACK TO CLIENT  ??????
                    outS.println(n);
                    outS.flush();

Author

Commented:
from line 87 i changed to below "outS.flush();" :

                //send and read from Svr  #??????????????????? HOW CAN I GET DATA FROM CLIENT AND SEND TO UPPERSER THEN RETURN THE RESULT BACK TO CLIENT  ??????
                outS.println(n);
                outS.flush();
                System.out.println(n + " were sent to upper server");
                
                while ((hlr_out = inS.readLine()) != null) {                                  
             out.println(inS.readLine());
                      out.flush();
      }

the resulf of each command request from client can be return more then one line(suppose there are 15 lines)
While i try to perform from two clients, some part of resulf of client 1 (e.g from line 10 to 15) return in Client 2... and result of command from client 2 show only 9 or 10 lines!
if i start 3rd client, it return the rest of resulf of client2 plus some record of 3rd result!

How, to fix these? and how can i get thread ID to be appended in those result?

CEHJ: could you gave me the sample code of your above comment?

thanks,
Java Developer
CERTIFIED EXPERT
Top Expert 2010
Commented:
thats because you on;ly have a single connection to the upper server.
you need ech client to open its own connection to the upper server. ie. open it in the run() method

Not the solution you were looking for? Getting a personalized solution is easy.

Ask the Experts

Author

Commented:
but before run() i also need to open the connection for login command(see line 57, 58) !
Do i need to create separate connection? By my idea i want to have only one connection to Upper Server since it is limited the number of connection !

thanks,
Mick BarryJava Developer
CERTIFIED EXPERT
Top Expert 2010

Commented:
if u only have opne connection to upper server then you can only have one client talking to it at a time.
you could still do the login inside the run() (for each connection).

CERTIFIED EXPERT
Top Expert 2016

Commented:
All you need to do is to hand off, in main a Socket to each instance of the echo server. Change the ctor to


public _13PoolEchoServer(Socket socket) {
        this.socket = socket;
   }            

and treat each client connection totally separately, communicating directly with each through 'socket'

Author

Commented:
well, my idea is to keep live connection to upper server... so any request command from client will use the existing connection from my application to upper server.

I'm not really understand this >>> All you need to do is to hand off, in main a Socket to each instance of the echo server. Change the ctor to
and i already call constructor for each thread (pls, see on line: 44)
Mick BarryJava Developer
CERTIFIED EXPERT
Top Expert 2010

Commented:
in that case you'll need to synchronise access to the upper server so only one send commands at a time.
something like:

public synchronized String getResponseFromUpperServer(String request)
{
   // communicate with upper server here
}
CERTIFIED EXPERT
Top Expert 2016

Commented:
>>so any request command from client will use the existing connection from my application to upper server.

Why would you want to do that? If you make all threads depend on this one connection

a. you'll need to synchronize access to it
b. it's tantamount to having it single-threaded in the first place

You're really making this more complex than it need be for no visible advantage. This implementation does what i suggested:

http://gd.tuwien.ac.at/languages/java/GoToJava2/examples/EchoServer.java

Author

Commented:
>>so any request command from client will use the existing connection from my application to upper server.
Because I think the process would be faster then reconnect to UpperServer by sending login command again and again. Onemore thing the number of connection to Upper Server is limited at the same time.

What is your idea? if we don't think of limited connection which way is faster and practical solution???

thanks,

Author

Commented:
and what i'm doing is not just echo server it act as midleware which use to listening request from client and send to other server("separately") then get the result back to client!
CERTIFIED EXPERT
Top Expert 2016

Commented:
>>What is your idea? if we don't think of limited connection which way is faster and practical solution???

The one at the link i posted

>>and what i'm doing is not just echo server...

Then you should synchronize access to the upper server
Mick BarryJava Developer
CERTIFIED EXPERT
Top Expert 2010

Commented:
> Because I think the process would be faster then reconnect to UpperServer by sending login command again and

wouldn't make much if any any difference. what u gain would be lost by multiple clients waiting on their 'turn' to send commands. Giving each client its own connection would give you the best thuput, and add a connection pool to improve things more.

Author

Commented:
ok, it work with separated connection !!! but let say i limited 10 thread only at a time--- how can i put the other attempt process in Q(e.g: process #11 or 12...)

thanks,
Mick BarryJava Developer
CERTIFIED EXPERT
Top Expert 2010

Commented:
my earlier suggestion to use synchronisation would do that.

Author

Commented:
i will consider "Synchronisation" later, just now i'm not familiar with this!

thank all for your help!!!
Mick BarryJava Developer
CERTIFIED EXPERT
Top Expert 2010

Commented:
why did u accept that answer, it just repeated what I had already said???
CERTIFIED EXPERT
Top Expert 2016

Commented:
:-)
Mick BarryJava Developer
CERTIFIED EXPERT
Top Expert 2010

Commented:
> ok, it work with separated connection !!!

which I suggested

Author

Commented:
ooh yeash-- sorry!
how can i score you again!!!
CERTIFIED EXPERT
Top Expert 2016

Commented:
You can reopen the q to redistribute points
CERTIFIED EXPERT
Top Expert 2016

Commented:
>>ooh yeash-- sorry!

Can we have clarification on this point please ikhmer? AFAICS there was a distinct difference in approach advocated in each case

Author

Commented:
actualy you are all give me the right answer, but what i have done is follow by one connection for each instance!

I'd like to give you all the same credit and many thank for your kind support!!!
Mick BarryJava Developer
CERTIFIED EXPERT
Top Expert 2010

Commented:
no confusion that I can see, the approach that was used is what I suggested :)
Mick BarryJava Developer
CERTIFIED EXPERT
Top Expert 2010

Commented:
> but what i have done is follow by one connection for each instance!

which is what i suggested

> I'd like to give you all the same credit and many thank for your kind support!!!

thats not how ee works, otherwise everyone would just copy other experts suggestions.

Author

Commented:
so, what should i do then? :-)
CERTIFIED EXPERT
Top Expert 2016

Commented:
The idea of EE is not to be browbeaten into how you distribute your *own* points ;-)

Author

Commented:
I saw only Object and Cehj who always answer my question... and you both help me alot!

anyway, i will make it fare for you all! :-)
Access more of Experts Exchange with a free account
Thanks for using Experts Exchange.

Create a free account to continue.

Limited access with a free account allows you to:

  • View three pieces of content (articles, solutions, posts, and videos)
  • Ask the experts questions (counted toward content limit)
  • Customize your dashboard and profile

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.