Hello,

I'm having touble with my HTTP tunnelling servlet and its driving me crazy.
The tunnel works fine for a single user. However when another user connects
to the tunnel the servlet does not perform how I would expect it to.

The problem is, that when another user sends a message. ALL instances of the
variables seem to swap over to the most recent. However the threads still
all run. So, if mr x and mr y are in a meeting. Mr x joined first, he says
'hello'. Hello is sent and recieved once how I would expect it to do it.
However, now mr y joins and says 'hello'. and he recieves the messages for
himself AND for mr x.

This is driving me insane and I can't seem to find a way around it, I don't
understand why the entire data structure is being overwritten when it is a
different request for a different user. The sockets are different, yet when
i do the test, they aren't! But the server isnt sending the message out on
the wrong socket. I've tested that. It's somehow the right sockets,
recieving the right messages, but then sending them to the wrong place. But
how can this be? It makes no sense to me.

The code for the tunnel is below.

Stuart Stephen


import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.ServletException.*;
import javax.servlet.UnavailableException.*;
import java.lang.Exception.*;
import java.io.*;
import java.util.*;
import java.net.*;

public class TestTunnel extends HttpServlet {

  Hashtable connections = null;

  protected void service(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException  {
    try {
      String method = (String)req.getParameter("method").trim();

      if(method!=null && !method.equalsIgnoreCase("")) {
        if(method.equalsIgnoreCase("connect")) connectUser(req, res,
(String)req.getParameter("mid").trim(), "",
(String)req.getParameter("email").trim());
        else if(method.equalsIgnoreCase("msg"))
msgServer((String)req.getParameter("mid").trim(), "",
(String)req.getParameter("email").trim(),
(String)req.getParameter("msg").trim());
        else {
          System.err.println("redirecting user");
          res.sendRedirect("http://www.disney.com";);
        }
      }
    }
    catch(Exception e) {
      e.printStackTrace();
    }
  }

  protected synchronized void msgServer(String mid, String uid, String
email, String msg) {
    if(connections!=null) {
      try {
        System.err.println("msgServer()");
        Hashtable meet = (Hashtable)connections.get(mid+""+uid+""+email);
        if(meet!=null) {
          ((ToServer)meet.get("ToServer")).write(msg);
        }
        else System.err.println("msgServer(): meet == null");
      }
      catch(Exception e) {
        e.printStackTrace();
      }
    }
    else System.err.println("msgServer(): No connections to use.");
  }

  protected void connectUser(HttpServletRequest req, HttpServletResponse
res, String mid, String uid, String email) {
    try {
      System.err.println("CONNECTING "+mid+""+uid+""+email);

      Socket socket = new Socket("127.0.0.1", 3000);
      ToApplet app = new ToApplet(socket, res, mid, uid, email);
      ToServer ser = new ToServer(socket, req, mid, uid, email);

      app.start();
      ser.start();

      Hashtable meet = new Hashtable();
      meet.put("ToApplet", app);
      meet.put("ToServer", ser);
      meet.put("Socket", socket);
      if(connections==null) connections = new Hashtable();
      connections.put(mid+""+uid+""+email, meet.clone());

      while(meet!=null && ((ToServer)meet.get("ToServer")).isAlive() &&
((ToApplet)meet.get("ToApplet")).isAlive()) {
        try {
          System.err.println("Threads alive");
          Thread.sleep(1000);
        }
        catch(Exception ex) {
          ex.printStackTrace();
        }
      }

      if(meet!=null) {
        try { ((ToServer)meet.get("ToServer")).objIn.close(); }
catch(Exception ex) { }
        try { ((ToServer)meet.get("ToServer")).sockObjOut.close(); }
catch(Exception ex) { }
        try { ((ToApplet)meet.get("ToApplet")).objOut.close(); }
catch(Exception ex) { }
        try { ((ToApplet)meet.get("ToApplet")).sockObjIn.close(); }
catch(Exception ex) { }
        try { ((Socket)meet.get("Socket")).close(); } catch(Exception ex)
{ }
      }
      else System.err.println("connectUser(): meet == null");
      connections.remove(mid+""+uid+""+email);
    }
    catch(Exception e) {
      e.printStackTrace();
    }
    System.err.println("DISCONNECTED "+mid+""+uid+""+email);
  }
}

class ToApplet extends Thread implements Runnable {
  DataInputStream sockObjIn = null;
  DataOutputStream objOut = null;

  String mid = null;
  String uid = null;
  String email = null;
  Socket socket = null;
  HttpServletResponse res = null;

  boolean isAlive = true;

  public ToApplet(Socket socket, HttpServletResponse res, String mid, String
uid, String email) {
    try {
      this.objOut = new DataOutputStream(res.getOutputStream());
      this.sockObjIn = new DataInputStream(socket.getInputStream());
      this.mid = mid;
      this.uid = uid;
      this.email = email;
      this.socket = socket;
      this.res = res;
    }
    catch(Exception e) {
      e.printStackTrace();
    }
  }

  public void run() {
    try {
      String obj = null;
      while((obj = this.sockObjIn.readLine())!=null) {
        System.err.println("Read a line from "+mid+""+uid+""+email+"
"+sockObjIn.toString()+" "+socket.toString()+" "+res.toString());  //
obviously coming from the right socket, but the variables are incorrect.
        this.write(obj);
      }
    }
    catch(Exception e) {
      e.printStackTrace();
    }
    isAlive = false;
  }

  public boolean connIsAlive() {
    return isAlive;
  }

  public void write(String msg) {
    try {
      System.err.println("S-->A "+mid+""+uid+""+email+" "+msg);
      objOut.writeUTF(msg+"\r\n");
      objOut.flush();
    }
    catch(Exception e) {
      e.printStackTrace();
      isAlive = false;
    }
  }
}

class ToServer extends Thread implements Runnable {
  DataInputStream objIn = null;
  DataOutputStream sockObjOut = null;

  String mid = null;
  String uid = null;
  String email = null;

  boolean isAlive = true;

  public ToServer(Socket socket, HttpServletRequest req, String mid, String
uid, String email) {
    try {
      this.sockObjOut = new DataOutputStream(socket.getOutputStream());
      this.objIn = new DataInputStream(req.getInputStream());
      this.mid = mid;
      this.uid = uid;
      this.email = email;
    }
    catch(Exception e) {
      e.printStackTrace();
    }
  }

  public void run() {
    try {
      while(isAlive) {
        Thread.sleep(1000);
      }
    }
    catch(Exception e) {
    }
    System.err.println("ToServer() thread finished.");
  }

  public boolean connIsAlive() {
    return isAlive;
  }

  public void write(String msg) {
    try {
      System.err.println("S<--A "+mid+""+uid+""+email+" "+msg);
      sockObjOut.writeUTF(msg+"\r\n");
      sockObjOut.flush();
    }
    catch(Exception e) {
      e.printStackTrace();
      isAlive = false;
    }
  }
}



--
To unsubscribe, e-mail:
<mailto:[EMAIL PROTECTED]>
For additional commands, e-mail:
<mailto:[EMAIL PROTECTED]>



--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to