Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/act365/net/GeneralDatagramSocketImpl.java


1   /*
2    * JSocket Wrench
3    * 
4    * Copyright (C) act365.com October 2003
5    * 
6    * Web site: http://www.act365.com/wrench
7    * E-mail: developers@act365.com
8    * 
9    * The JSocket Wrench library adds support for low-level Internet protocols
10   * to the Java programming language.
11   * 
12   * This program is free software; you can redistribute it and/or modify it 
13   * under the terms of the GNU General Public License as published by the Free 
14   * Software Foundation; either version 2 of the License, or (at your option) 
15   * any later version.
16   *  
17   * This program is distributed in the hope that it will be useful, 
18   * but WITHOUT ANY WARRANTY; without even the implied warranty of 
19   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 
20   * Public License for more details.
21   * 
22   * You should have received a copy of the GNU General Public License along with 
23   * this program; if not, write to the Free Software Foundation, Inc., 
24   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25   */
26  
27  package com.act365.net;
28  
29  import java.io.*;
30  import java.net.*;
31  
32  /**
33   * GeneralDatagramSocketImpl extends <code>java.net.DatagramSocketImpl</code>
34   * and provides native implementations of all of its abstract methods. The
35   * class remains abstract because it leaves its <code>create()</code> method
36   * undefined - it is up to subclasses to specify the parameters that will
37   * be used to create the underlying socket.
38   */
39  
40  public abstract class GeneralDatagramSocketImpl extends DatagramSocketImpl {
41  
42    /**
43     Creates a new unconnected socket. The socket is allowed to be of any type
44     and use any protocol supported by the underlying operating system. The method
45     <code>create()</code> - note no arguments - should be defined in a subclass
46     and call the version in the superclass with the parameters set
47     appropriately. When a raw socket is set up, the user has the option to write
48     his own IP header sockets (set <code>headerincluded</code> to <code>true</code>)
49     or to allow the operating system to write the headers. NB The option does
50     not exist on Windows, where the <code>IP_HDRINCL</code> symbol is 
51     unsupported.
52     @see com.act365.net.SocketConstants
53     @param socketType the socket type as defined in <code>SocketConstants</code> e.g. SOCK_RAW
54     @param protocol the protocol as defined in <code>SocketConstants</code> e.g. IPPROTO_UDP
55     @param headerincluded whether the user will complete the IP header 
56    */
57  
58    public void create ( int socketType , int protocol , boolean headerincluded ) throws SocketException {
59  
60      int sd = _socket( SocketConstants.AF_INET , socketType , protocol , headerincluded );
61  
62      fd = new FileDescriptor();
63  
64      setSocketDescriptor( fd , sd );
65    }
66  
67    native static int _socket( int addressFamily , int socketType , int protocol , boolean headerincluded );
68  
69    /**
70     Binds this socket to a local port.
71     @param localPort number of the local port
72     @param inetAddress local IP address
73    */
74  
75    public void bind( int localPort , InetAddress inetAddress ) throws SocketException {
76  
77      _bind( getSocketDescriptor( fd ) , inetAddress.getAddress() , localPort );
78  
79      this.localPort = localPort ;
80    }
81  
82    native static int _bind( int sd , byte[] ipAddress , int port );
83  
84    /**
85     Closes this socket.
86    */
87  
88    public void close() {
89  
90      _close( getSocketDescriptor( fd ) );
91    }
92  
93    native static int _close( int sd );
94  
95    /**
96     Polls until a datagram packet is received. Once received, the parameter
97     <em>sender</em> is populated with the address of the sender and the
98     port number is returned as an <code>int</code>. Note that the JDK1.4 API
99     documentation states that the IP address should be returned as an <code>int</code>
100    - however, the JDK1.1 API documentation states that the port number should be 
101    returned. I have implemented the JDK1.1 behaviour because it seems more 
102    sensible - an IP address is always stored in an <code>InetAddress</code> 
103    object in Java.  
104    @param sender address of sender - to be populated by the function call
105    @return port used by sender
106   */
107 
108   public int peek( InetAddress sender ) throws IOException {
109     byte[] buffer = new byte[0];
110     DatagramPacket dgram = new DatagramPacket( buffer , buffer.length );
111   dgram.setAddress( GeneralSocketImpl.createInetAddress( SocketConstants.AF_INET , new byte[]{0,0,0,0} ));
112   _receive( getSocketDescriptor( fd ) , dgram , SocketConstants.MSG_PEEK );
113   sender = dgram.getAddress();
114   return dgram.getPort();
115   }
116 
117   /**
118    * Extracts the next DatagramPacket and returns the port number. Note
119    * that the behaviour differs from that described in the JDK1.4
120    * documentation.
121    * @see peek
122    * @param p next packet received
123    * @return port to have received the packet
124    */
125   
126   public int peekData( DatagramPacket p ) throws IOException {
127     byte[] buffer = new byte[ 0 ];
128     p.setData( buffer );
129   p.setAddress( GeneralSocketImpl.createInetAddress( SocketConstants.AF_INET , new byte[]{0,0,0,0} ));
130   _receive( getSocketDescriptor( fd ) , p , SocketConstants.MSG_PEEK );
131   return p.getPort();
132   }
133   
134   /**
135    Reads a datagram packet.
136    @param dgram packet to be populated
137   */
138 
139   public void receive( DatagramPacket dgram ) throws IOException {
140     dgram.setAddress( GeneralSocketImpl.createInetAddress( SocketConstants.AF_INET , new byte[]{0,0,0,0} ));
141     _receive( getSocketDescriptor( fd ) , dgram , 0 );
142   }
143 
144   native static void _receive( int sd , DatagramPacket dgram , int flags );
145 
146   /**
147    Sends a datagram packet.
148    @param dgram packet to be sent
149   */
150 
151   public void send( DatagramPacket dgram ) throws IOException {
152 
153     _send( getSocketDescriptor( fd ) , 
154            dgram.getAddress().getAddress() , 
155            dgram.getPort() , 
156            dgram.getData() , 
157            dgram.getLength() );
158   }
159 
160   native static void _send( int sd , byte[] ipAddress , int port , byte[] data , int length );
161 
162   /**
163    Retrieves time-to-live for multicast sockets.
164    NB Multicast sockets are not yet supported.
165   */
166 
167   public int getTimeToLive() throws IOException {
168     throw new IOException("Multicast sockets not supported");
169   }
170 
171   /**
172    Retrieves time-to-live for multicast sockets.
173    NB Multicast sockets are not yet supported.
174    The method leads to a deprecation warning in JDK1.3 but has to be
175    provided if <code>java.net.DatagramSocketImpl</code> is to be extended.
176   */
177 
178   public byte getTTL() throws IOException {
179     throw new IOException("Multicast sockets not supported");    
180   }
181   
182   /**
183    Joins a multicast group. (JDK1.3)
184    NB Multicast sockets are not yet supported.
185   */
186 
187   public void join( InetAddress groupAddr ) throws IOException {
188     throw new IOException("Multicast sockets not supported");
189   }
190 
191   /**
192    Joins a multicast group. (JDK1.4)
193    NB Multicast sockets are not yet supported.
194   */
195 
196   public void joinGroup( SocketAddress mcastaddr , NetworkInterface netIf ) throws IOException {
197   throw new IOException("Multicast sockets not supported");
198   }
199   
200   /**
201    Leaves a multicast group. (JDK1.3)
202    NB Multicast sockets are not yet supported.
203   */
204 
205   public void leave( InetAddress groupAddr ) throws IOException {
206     throw new IOException("Multicast sockets not supported");
207   }
208 
209   /**
210    Leaves a multicast group. (JDK1.4)
211    NB Multicast sockets are not yet supported.
212   */
213 
214   public void leaveGroup( SocketAddress mcastaddr , NetworkInterface netIf ) throws IOException {
215   throw new IOException("Multicast sockets not supported");
216   }
217   
218   /**
219    Sets time-to-live for multicast sockets.
220    NB Multicast sockets are not yet supported.
221   */
222 
223   public void setTimeToLive( int ttl ) throws IOException {
224     throw new IOException("Multicast sockets not supported");
225   }
226 
227   /**
228    Sets time-to-live for multicast sockets.
229    NB Multicast sockets are not yet supported.
230    The method leads to a deprecation warning in JDK1.3 but has to be
231    provided if <code>java.net.DatagramSocketImpl</code> is to be extended.
232   */
233 
234   public void setTTL( byte ttl ) throws IOException {
235     throw new IOException("Multicast sockets not supported");
236   }
237   
238   /**
239    Gets the socket descriptor from a <code>java.io.FileDescriptor</code> object.
240    NB Java provides no public access to the value of the descriptor so
241    it has to be extracted using native code.
242   */
243 
244   public static int getSocketDescriptor( FileDescriptor fd ){
245     return _getSocketDescriptor( fd );
246   }
247 
248   native static int _getSocketDescriptor( FileDescriptor fd );
249 
250   /**
251    Sets the socket descriptor for a <code>java.io.FileDescriptor</code> object.
252    NB Java provides no public access to the descriptor so its value has to
253    be set using native code.
254   */
255 
256   public static void setSocketDescriptor( FileDescriptor fd , int sd ){
257     _setSocketDescriptor( fd , sd );
258   }
259 
260   native static void _setSocketDescriptor( FileDescriptor fd , int sd );
261 
262   /**
263    Sets the value of a socket option. The value has to be an 
264    <code>Integer</code> object.
265    @param optID option as defined in <code>java.net.SocketConstants</code>
266    @param value an <code>Integer</code> object that wraps the new value
267   */
268 
269   public void setOption( int optID , Object value ) throws SocketException {
270 
271     if( _setOption( getSocketDescriptor( fd ) , optID , value ) < 0 ){
272       throw new SocketException();
273     }
274   }
275 
276   static native int _setOption( int socketDescriptor , int optionName , Object newValue );
277 
278   /**
279    Gets the value of a socket option. The returned value will be an
280    <code>Integer</code> object.
281    @param optID option as defined in <code>java.net.SocketConstants</code>
282   */
283 
284   public Object getOption( int optID ) throws SocketException {
285 
286     Object value = _getOption( getSocketDescriptor( fd ) , optID );
287 
288     return value ;
289   }
290 
291   static native Object _getOption( int socketDescriptor , int optionName ) throws SocketException ;
292 };
293 
294