Main Page | Packages | Class Hierarchy | Class List | Directories | File List | Class Members

SocketHandler.java

Go to the documentation of this file.
00001 /*
00002  * SocketHandler.java
00003  *
00004  * Created on den 25 oktober 2004, 14:23
00005  */
00006 /*
00007 Copyright (C) 2004  Anders Hedstrom
00008  
00009 This program is free software; you can redistribute it and/or
00010 modify it under the terms of the GNU General Public License
00011 as published by the Free Software Foundation; either version 2
00012 of the License, or (at your option) any later version.
00013  
00014 This program is distributed in the hope that it will be useful,
00015 but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017 GNU General Public License for more details.
00018  
00019 You should have received a copy of the GNU General Public License
00020 along with this program; if not, write to the Free Software
00021 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00022  */
00023 
00024 package net.alhem.jsockets;
00025 
00026 import java.nio.channels.SelectableChannel;
00027 import java.nio.channels.SelectionKey;
00028 import java.nio.channels.Selector;
00029 import java.nio.channels.ServerSocketChannel;
00030 import java.nio.channels.SocketChannel;
00031 import java.util.Iterator;
00032 import java.util.List;
00033 import java.util.Map;
00034 import java.util.Set;
00035 import java.util.Vector;
00036 
00041 public class SocketHandler
00042 {
00043     
00045     public SocketHandler()
00046     {
00047         this(null);
00048     } // SocketHandler
00049     
00050     public SocketHandler(StdLog log)
00051     {
00052         m_log = log;
00053         try
00054         {
00055             m_selector = Selector.open();
00056         }
00057         catch (java.io.IOException e)
00058         {
00059             LogError(null, "SocketHandler", 0, e.toString(), SocketHandler.LOG_LEVEL_FATAL);
00060         }
00061         m_sockets = new Vector<Socket>();
00062         //
00063         System.out.println("m_log is " + ((m_log == null) ? "NULL" : "OK"));
00064         System.out.println("m_selector is " + ((m_selector == null) ? "NULL" : "OK"));
00065     } // SocketHandler
00066     
00067     public void LogError(Socket s,String usertxt,int errcode,String errtxt,int loglevel)
00068     {
00069         if (m_log != null)
00070         {
00071             m_log.error(this, s, usertxt, errcode, errtxt, loglevel);
00072         }
00073     } // LogError
00074     
00075     public void Select(long secs,long millisecs)
00076     {
00077         // See if we've had any activity -- either
00078         // an incoming connection, or incoming data on an
00079         // existing connection
00080         try
00081         {
00082             int num = m_selector.select(secs * 1000 + millisecs);
00083             
00084             // If we don't have any activity, loop around and wait
00085             // again
00086             if (num == 0)
00087             {
00088                 return;
00089             }
00090             
00091             // Get the keys corresponding to the activity
00092             // that has been detected, and process them
00093             // one by one
00094             Set keys = m_selector.selectedKeys();
00095             Iterator it = keys.iterator();
00096             while (it.hasNext())
00097             {
00098                 // Get a key representing one of bits of I/O
00099                 // activity
00100                 SelectionKey key = (SelectionKey)it.next();
00101                 
00102                 // What kind of activity is it?
00103                 if ((key.readyOps() & SelectionKey.OP_READ) == SelectionKey.OP_READ)
00104                 {
00105                     SocketChannel ch = (SocketChannel)key.channel();
00106                     java.net.Socket ss = (java.net.Socket)ch.socket();
00107                     Socket s = (Socket)key.attachment();
00108                     if (s != null)
00109                     {
00110 //                        System.out.println(s + ": OnRead");
00111                         s.OnRead();
00112                         if (s.LineProtocol())
00113                         {
00114                             s.ReadLine(); // eat ibuf to m_line, calls OnLine
00115                         }
00116                     }
00117                 }
00118                 if ((key.readyOps() & SelectionKey.OP_WRITE) == SelectionKey.OP_WRITE)
00119                 {
00120                     SocketChannel ch = (SocketChannel)key.channel();
00121                     java.net.Socket ss = (java.net.Socket)ch.socket();
00122                     Socket s = (Socket)key.attachment();
00123                     if (s != null)
00124                     {
00125 //                        System.out.println(s + ": OnWrite");
00126                         s.OnWrite();
00127                     }
00128                 }
00129                 if ((key.readyOps() & SelectionKey.OP_ACCEPT) == SelectionKey.OP_ACCEPT)
00130                 {
00131                     ServerSocketChannel ch = (ServerSocketChannel)key.channel();
00132                     java.net.ServerSocket ss = (java.net.ServerSocket)ch.socket();
00133                     Socket s = (Socket)key.attachment();
00134                     if (s != null)
00135                     {
00136 //                        System.out.println(s + ": OnRead(ACCEPT)");
00137                         s.OnRead(); // ListenSocket.OnRead will call OnAccept on new Socket
00138                     }
00139                 }
00140                 if ((key.readyOps() & SelectionKey.OP_CONNECT) == SelectionKey.OP_CONNECT)
00141                 {
00142                     SocketChannel ch = (SocketChannel)key.channel();
00143                     java.net.Socket ss = (java.net.Socket)ch.socket();
00144                     Socket s = (Socket)key.attachment();
00145                     if (s != null)
00146                     {
00147 //                        System.out.println(s + ": OnConnect");
00148                         ch.finishConnect();
00149                         s.SetConnecting(false);
00150                         s.GetKey().interestOps(SelectionKey.OP_READ);
00151                         s.OnConnect();
00152                     }
00153                 }
00154                 
00155             } // while
00156             keys.clear();
00157             
00158             // deregister
00159             it = m_selector.keys().iterator();
00160             boolean bRemoved = false;
00161             while (it.hasNext())
00162             {
00163                 // Get a key representing one of bits of I/O
00164                 // activity
00165                 SelectionKey key = (SelectionKey)it.next();
00166                 Socket p = (Socket)key.attachment();
00167                 if (p.CloseAndDelete())
00168                 {
00169                     p.OnDelete(); // OnDelete closes Channel
00170                     key.cancel();
00171                     m_sockets.remove(p); // no longer Valid
00172                     bRemoved = true;
00173                 }
00174             } // while - check for delete
00175             if (bRemoved)
00176             {
00177                 PrintSockets();
00178             }
00179 
00180         } catch ( java.io.IOException e)
00181         {
00182             LogError(null, "Select", 0, e.toString(), SocketHandler.LOG_LEVEL_ERROR);
00183         }
00184     } // Select
00185     
00186     public void Add(Socket x)
00187     {
00188         SelectableChannel ch = x.GetChannel();
00189         try
00190         {
00191             SelectionKey key = ch.register( m_selector, ch.validOps(), x);
00192             x.SetKey(key);
00193             x.OnInitialOps();
00194             m_sockets.add(x);
00195             PrintSockets();
00196         } catch (Exception e)
00197         {
00198             LogError(x, "Add", 0, e.toString(), SocketHandler.LOG_LEVEL_ERROR);
00199         }
00200     } // Add
00201 
00202     public boolean Valid(Socket x)
00203     {
00204         return m_sockets.contains(x);
00205     } // Valid
00206 
00207     public void PrintSockets()
00208     {
00209         System.out.println(getClass().getSimpleName() + ": Current socket list");
00210         for (int i = 0; i < m_sockets.size(); i++)
00211         {
00212             Socket x = m_sockets.get(i);
00213             System.out.println(x);
00214         }
00215     } // PrintSockets
00216     
00217     // "defines"
00218     public static final int LOG_LEVEL_INFO = 0;
00219     public static final int LOG_LEVEL_WARNING = 1;
00220     public static final int LOG_LEVEL_ERROR = 2;
00221     public static final int LOG_LEVEL_FATAL = 3;
00222     
00223     //
00224     private Selector m_selector;
00225     private StdLog m_log;
00226     private Vector<Socket> m_sockets;
00227 }

Generated on Fri Oct 29 14:11:18 2004 for Java Sockets by  doxygen 1.3.9.1