1 2 Previous Next 17 Replies Latest reply on Dec 15, 2007 11:39 PM by 800351

    Threading with sockets

    807603
      I need a little help here please. What I am trying to do is have my application always wait for an incomming connection. When a socket connection has been made, create a new thread to handle that connection and continue to wait for any more incomming connections.

      I know I need a thread here, but I'm not sure exactly where I need one
          public static void main(String[] args)
          {
              while (true)
              {
                  try
                  {
                      Socket socket = new ServerSocket(54321).accept();
                      BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
      
                      while (!in.ready())
                      {
                      }
                      System.out.println("Cancelling switch: " + in.readLine());
                      in.close();
                  }
                  catch (IOException ex)
                  {
                      ex.printStackTrace();
                  }
              }
          }
        • 1. Re: Threading with sockets
          800351
          Read the reply at:
          http://forum.java.sun.com/thread.jspa?threadID=5246527&tstart=0
          • 2. Re: Threading with sockets
            807603
            I accidentally replied to the other thread, but something like this:
                public static void main(String[] args)
                {
                    while (true)
                    {
                        try
                        {
                            Socket socket = new ServerSocket(54321).accept();
                            BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            
                            while (!in.ready())
                            {
                            }
            
                            new Thread()
                            {
                                @Override
                                public void run()
                                {
                                    System.out.println("Cancelling switch: " + in.readLine());
                                    in.close();
                                    Thread.currentThread().interrupt();
                                }
                            };
                            Thread.currentThread().start();
            
                        }
                        catch (IOException ex)
                        {
                            ex.printStackTrace();
                        }
                    }
                }
            The only problem is socket and in are inside the inner class and need to be final, but that won't work right then.

            Edited by: tristanlee85 on Dec 14, 2007 2:44 AM
            • 3. Re: Threading with sockets
              EJP
              The only problem
              No, a much bigger problem is you haven't solved the problem. Constructing the input and output streams and the actual I/O should all go inside the thread. Also calling in.ready() is a complete waste of time. Just block in the read, setting a timeout if necessary.
              • 4. Re: Threading with sockets
                807603
                ejp wrote:
                Also calling in.ready() is a complete waste of time. Just block in the read, setting a timeout if necessary.
                I think I might be confused or misunderstanding. This application is going to run for hours at a time and will accept incoming sockets whenever. If I set a timeout, how would it stay open to accept anything incoming?
                • 5. Re: Threading with sockets
                  800351
                  @OP
                  read:
                  http://forum.java.sun.com/thread.jspa?threadID=5246527
                  • 6. Re: Threading with sockets
                    EJP
                    So set a long timeout? Don't set a timeout? Set a timeout and think about how many timeouts you've had on that connection? and have a policy about how many is too many? or how long is too long?

                    Any network application needs a read timeout IMO. Otherwise you can't detect network or connection failure when blocked in a read.
                    • 7. Re: Threading with sockets
                      807603
                      I'm still messing around trying to get some proper output. I definately isn't a final structure of the code, but it's something to try and get me started. After the socket has been created and all and data is received, I close the socket and set it to null then run through the loop again, but even with socket being null, it still says the address is in use. How is this?
                          public static void main(String[] args)
                          {
                              while (true)
                              {
                                  if (socket == null)
                                  {
                                      System.out.println("In the WHILE loop.\n");
                                      try
                                      {
                                          socket = new ServerSocket(54321).accept();
                                          in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                      
                                          while (!in.ready())
                                          {
                                          }
                      
                                          socketThread = new Thread()
                                          {
                      
                                              @Override
                                              public void run()
                                              {
                                                  System.out.println("In the new Thread.\n");
                                                  try
                                                  {
                                                      System.out.println("Cancelling switch: " + in.readLine());
                                                      in.close();
                                                      socket.close();
                                                      socket = null;
                                                      if (socket == null)
                                                      {
                                                          System.out.println("socket is null");
                                                      }
                                                      socketThread.interrupt();
                                                  }
                                                  catch (IOException ex)
                                                  {
                                                      System.out.println(ex.getMessage());
                                                  }
                                              }
                                          };
                                          System.out.println("Starting the thread.\n");
                                          socketThread.start();
                                      }
                                      catch (Exception ex)
                                      {
                                          System.out.println("Address already in use. Sleeping for 5 seconds...");
                                          try
                                          {
                                              Thread.sleep(5000);
                                          }
                                          catch (Exception e)
                                          {
                      
                                          }
                                      }
                                  }
                              }
                          }
                      Output:
                      C:\Documents and Settings\Tristan\Desktop\Java\TrailerSwitchServer\dist>java -ja
                      r TrailerSwitchServer.jar
                      In the WHILE loop.
                      
                      Starting the thread.
                      
                      In the new Thread.
                      
                      Cancelling switch: 74904
                      socket is null
                      In the WHILE loop.
                      
                      Address already in use. Sleeping for 5 seconds...
                      In the WHILE loop.
                      
                      Address already in use. Sleeping for 5 seconds...
                      In the WHILE loop.
                      
                      Address already in use. Sleeping for 5 seconds...
                      
                      C:\Documents and Settings\Tristan\Desktop\Java\TrailerSwitchServer\dist>
                      • 8. Re: Threading with sockets
                        EJP
                        That's because you keep trying to create a new ServerSocket on the same port number.

                        This is still pretty bizarre. I suggest you read the Custom Networking part of the Java Tutorial before you go any further.
                        • 9. Re: Threading with sockets
                          800351
                          Your code == wrong code:
                              public static void main(String[] args)
                              {
                                  while (true)
                                  {
                                      if (socket == null)
                                      {
                                          System.out.println("In the WHILE loop.\n");
                                          try
                                          {
                                              socket = new ServerSocket(54321).accept();
                                              in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                          Here's the standard:
                          // only once in the whole life cycle of the server
                          ServerSocket ss = new ServerSocket(54321);
                          while (true){
                            Socket s = ss.accept();
                            // you should do the I/O and its preparation in each client handling thread
                            new Thread(new ClientHandler(s)).start();
                          }
                          
                          class ClientHandler implements Runnable{
                            Socket soc;
                          
                            public ClientHandler(Socket s){
                              soc = s;
                            }
                          
                            public void run(){
                              ...
                              ...
                            }
                          }
                          • 10. Re: Threading with sockets
                            807603
                            ejp wrote:
                            That's because you keep trying to create a new ServerSocket on the same port number.

                            This is still pretty bizarre. I suggest you read the Custom Networking part of the Java Tutorial before you go any further.
                            I know. I'm not coming here and posting without any research. I'm just not understanding it fully, but with the example below it has now clicked.

                            Thank you both!
                            • 11. Re: Threading with sockets
                              807603
                              Well with that example above I got everything working well. Thank you again.

                              One thing I notice is each time a new thread is created, the JVM seems to be using more and more space. The memory usage increases by increments of as large as 30kb each time the new thread is created. Should I be interrupting that thread once my method has completed?

                              Here are the important parts of my code:

                              TrailerSwitch.java
                                  public static void main(String[] args)
                                  {
                                      try
                                      {
                                          ServerSocket ss = new ServerSocket(54321);
                                          while (true)
                                          {
                                              Socket s = ss.accept();
                                              new Thread(new DataTransfer(s)).start();
                                          }
                                      }
                                      catch (IOException ex)
                                      {
                                          Logger.getLogger(TrailerSwitching.class.getName()).log(Level.SEVERE, null, ex);
                                      }
                                  }
                              DataTransfer.java
                              package trailerswitchserver;
                              
                              import java.io.BufferedReader;
                              import java.io.IOException;
                              import java.io.InputStreamReader;
                              import java.io.PrintWriter;
                              import java.net.ServerSocket;
                              import java.net.Socket;
                              
                              /**
                               *
                               * @author tristan
                               */
                              public class DataTransfer implements Runnable
                              {
                              
                                  static Socket soc;
                                  static BufferedReader in;
                                  String SERVER_ADDRESS = "192.168.1.100";
                              
                                  public DataTransfer(Socket s)
                                  {
                                      soc = s;
                                  }
                              
                                  public boolean cancelSwitch(int id)
                                  {
                                      if (sendRequest(id) && isRequested())
                                      {
                                          return true;
                                      }
                                      else
                                      {
                                          return false;
                                      }
                                  }
                              
                                  public static void getRequest()
                                  {
                                      try
                                      {
                                          in = new BufferedReader(new InputStreamReader(soc.getInputStream()));
                              
                                          while (!in.ready())
                                          {
                                          }
                              
                                          System.out.println("Cancelling switch: " + in.readLine());
                                          in.close();
                                          soc.close();
                                      }
                                      catch (IOException ex)
                                      {
                                          ex.printStackTrace();
                                      }
                                  }
                              
                                  public void run()
                                  {
                                      getRequest();
                                  }
                              }
                              • 12. Re: Threading with sockets
                                807603
                                The thread will terminate as soon as the run() method of the Runnable returns.

                                There is also an obvious sychronization bug in you DataTransfer class. Apparently your DataTransfer class is made to handle one single incomming request per instance. However, you declare the input stream and the socket as static. This means that those 2 variables will be shared between all instances of your DataTransfer class. If you are unlucky and you application receives several requests in a short time, it is very possible that one of your DataTransfer objects will modify the "in" variable while another one is still using it. causing all sorts of problem.

                                Solution to that problem: don't declare those 2 variables as Static.

                                second thing is that you should always close your input streams and sockets inside the "finally" part of a try-catch-finally block. Otherwise, if some problem occurs during the processing, your socket and output streams won't be properly closed.

                                If the code you posted is exactly your code, I can't see exactly where you would leak that memory. It might be in another place than you think.
                                • 13. Re: Threading with sockets
                                  EJP
                                  The while (!in.ready()) loop is still a complete waste of time.

                                  Even if it doesn't fry your CPU ...

                                  Just remove it. readLine() will block until something arrives.
                                  • 14. Re: Threading with sockets
                                    800351
                                    @OP tristanlee85
                                    You lack BASICS and STANDARD.
                                    You are running wild like a kite that have lost its tail, the stabilizer.
                                    Fill your big void by reading EJP's book.
                                    http://www.telekinesis.com.au/wipv3_6/page2/show.jsp?id=230165&db=Entries
                                    1 2 Previous Next