📄 protocol.java
字号:
/* * * * Copyright 1990-2007 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version * 2 only, as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License version 2 for more details (a copy is * included at /legal/license.txt). * * You should have received a copy of the GNU General Public License * version 2 along with this work; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa * Clara, CA 95054 or visit www.sun.com if you need additional * information or have any questions. */package com.sun.midp.io.j2me.datagram;import java.io.IOException;import java.io.InterruptedIOException;import javax.microedition.io.Datagram;import javax.microedition.io.UDPDatagramConnection;import javax.microedition.io.Connector;import javax.microedition.io.Connection;import com.sun.cldc.io.ConnectionBaseInterface;import com.sun.j2me.security.AccessController;import com.sun.j2me.security.InterruptedSecurityException;import com.sun.midp.io.NetworkConnectionBase;import com.sun.midp.io.HttpUrl;import com.sun.midp.io.Util;import com.sun.midp.io.j2me.push.PushRegistryInternal;import com.sun.midp.midlet.MIDletSuite;import com.sun.midp.midlet.MIDletStateHandler;import com.sun.midp.security.SecurityToken;import com.sun.midp.security.Permissions;import com.sun.midp.security.ImplicitlyTrustedClass;import com.sun.midp.security.SecurityInitializer;/** * This is the default "datagram://" protocol for J2ME that maps onto UDP. */public class Protocol implements UDPDatagramConnection, ConnectionBaseInterface { /** UDP client permission name. */ private static final String SERVER_PERMISSION_NAME = "javax.microedition.io.Connector.datagramreceiver"; /** UDP server permission name. */ private static final String CLIENT_PERMISSION_NAME = "javax.microedition.io.Connector.datagram"; /** * Inner class to request security token from SecurityInitializer. * SecurityInitializer should be able to check this inner class name. */ static private class SecurityTrusted implements ImplicitlyTrustedClass {}; /** This class has a different security domain than the MIDlet suite */ private static SecurityToken classSecurityToken = SecurityInitializer.requestToken(new SecurityTrusted()); /** Initialize the native network. */ static { NetworkConnectionBase.initializeNativeNetwork(); } /** Lock object for reading from the datagram socket */ private final Object readerLock = new Object(); /** Lock object for writing to the datagram socket */ private final Object writerLock = new Object(); /** * Handle to native datagram socket object. This is set and get only by * native code. */ private int nativeHandle = -1; /** Machine name from the URL connection string. */ private String host; /** Port number from the URL connection string. */ private int port; /** Open flag to indicate if the connection is currently open. */ private boolean open; /** This needs to know that if the owner is trusted. */ private boolean ownerTrusted; /** * Check for the required permission and open a connection to a target. * This method can be used with permissions greater than * the current MIDlet suite. * * @param checkSecurity true if security check is required * @param name URL for the connection, without the * without the protocol part * @param mode I/O access mode, see {@link Connector} * @return this Connection object * * @exception IllegalArgumentException If a parameter is invalid. * @exception ConnectionNotFoundException If the connection cannot * be found. * @exception IOException If some other kind of I/O error occurs. */ private Connection openPrimCommon(boolean checkSecurity, String name, int mode) throws IOException { MIDletStateHandler stateHandler = MIDletStateHandler.getMidletStateHandler(); MIDletSuite midletSuite = stateHandler.getMIDletSuite(); int incomingPort = 0; // parse name into host and port HttpUrl url = new HttpUrl("datagram", name); /* * Since we reused the <code>HttpUrl</code> parser, we must * make sure that there was nothing past the authority in the * URL. */ if (url.path != null || url.query != null || url.fragment != null) { throw new IllegalArgumentException("Malformed address " + name); } host = url.host; port = url.port; if (name.charAt(0) != '/' || name.charAt(1) != '/') { throw new IllegalArgumentException( "Protocol must start with slash slash"); } /* * If 'host' == null then we are a server endpoint at * port 'port'. * * If 'host' != null we are a client endpoint at a port * decided by the system and the default address for * datagrams to be send is 'host':'port' * * If 'host' and 'port' are omitted in * the name, then * the application is requesting a system assigned port * number. */ if (host == null) { if (checkSecurity) { try { // When asking permission use Internet protocol name. AccessController.checkPermission(SERVER_PERMISSION_NAME, "UDP:" + name); } catch (SecurityException se) { // Give back the connection to AMS PushRegistryInternal.checkInConnectionInternal( classSecurityToken, "datagram:" + name); if (se instanceof InterruptedSecurityException) { throw new InterruptedIOException( "Interrupted while trying to ask the user permission"); } throw se; } } if (port > 0) { incomingPort = port; } } else { if (port < 0) { throw new IllegalArgumentException("Missing port number"); } if (checkSecurity) { try { // When asking permission use Internet protocol name. AccessController.checkPermission(CLIENT_PERMISSION_NAME, "UDP:" + name); } catch (InterruptedSecurityException ise) { throw new InterruptedIOException( "Interrupted while trying to ask the user permission"); } } } if (checkSecurity) { try { AccessController.checkPermission( AccessController.TRUSTED_APP_PERMISSION_NAME); ownerTrusted = true; } catch (SecurityException se) { ownerTrusted = false; } } /* Check the mode parameter. (See NetworkConnectionAdapter). */ switch (mode) { case Connector.READ: case Connector.WRITE: case Connector.READ_WRITE: break; default: throw new IllegalArgumentException("Illegal mode"); } open0(incomingPort, midletSuite.getID()); open = true; return this; } /** * Open a connection to a target. This function would be used while * opening a dagaram connection from WMA. WMA version of datagram disables * the security check while opening a datagram connection * * <p> * The name string for this protocol should be: * "//[address:][port]" * * @param token a security token with the javax.microedition.io.datagram * permission set to the "allowed" level * @param name the target of the connection * @param mode a flag that is <code>true</code> if the caller * intends to write to the connection, ignored * @param timeouts a flag to indicate that the called * wants timeout exceptions, ignored * @return this connection * @exception IllegalArgumentException if a parameter is invalid * @throws IOException if an I/O operation failed * @exception SecurityException if a caller is not authorized for UDP */ public Connection openPrim(SecurityToken token, String name, int mode, boolean timeouts) throws IOException { token.checkIfPermissionAllowed(CLIENT_PERMISSION_NAME); return openPrimCommon(false, name, mode); } /** * Open a connection to a target. * <p> * The name string for this protocol should be: * "//[address:][port]" * * @param name the target of the connection * @param mode a flag that is <code>true</code> if the caller * intends to write to the connection, ignored * @param timeouts a flag to indicate that the called * wants timeout exceptions, ignored * @return this connection * @exception IllegalArgumentException if a parameter is invalid * @throws IOException if an I/O operation failed * @exception SecurityException if a caller is not authorized for UDP */ public Connection openPrim(String name, int mode, boolean timeouts) throws IOException { // IMPL NOTE remove usage of nativeHandle from Java if (nativeHandle != -1) { // This method should be called only once. throw new RuntimeException("Illegal state for operation"); } return openPrimCommon(true, name, mode); } /** * Ensure that the connection is open. * @exception IOException if the connection was closed */ void ensureOpen() throws IOException { if (!open) { throw new IOException("Connection closed"); } } /** * Get the maximum length a datagram can be. * * @return the length * @exception IOException if the connection was closed */ public int getMaximumLength() throws IOException { ensureOpen(); return getMaximumLength0(); } /** * Get the nominal length of a datagram. * * @return address the length * @exception IOException if the connection was closed */ public int getNominalLength() throws IOException { ensureOpen(); return getNominalLength0(); } /** * Send a datagram. * * @param dgram a datagram * @exception IOException if an I/O error occurs */ public void send(Datagram dgram) throws IOException { /* * Synchronization should be done for a writer lock and not for * the DatagramObject. For BSD based platforms, send on UDP sockets * are always synchronous(they never return IO_WOULDBLOCK). But having * a writer lock even for UDP send, would ensure that no more than one * thread is performing write for the same socket(handle) at the same * time. */ synchronized (writerLock) { int length; int ipNumber; int locPort; ensureOpen(); length = dgram.getLength(); // allow zero length datagrams to be sent if (length < 0) { throw new IOException("Bad datagram length"); } if (dgram instanceof DatagramObject) { DatagramObject dh = (DatagramObject)dgram; ipNumber = dh.ipNumber; if (ipNumber == 0) { throw new IOException( "No address in datagram"); } locPort = dh.port; } else { // address is a datagram url String addr; HttpUrl url; String locHost; addr = dgram.getAddress(); if (addr == null) { throw new IOException( "No address in datagram"); } url = new HttpUrl(addr); locHost = url.host; locPort = url.port; if (locHost == null) { throw new IOException("Missing host"); } if (locPort == -1) { throw new IOException("Missing port"); } ipNumber = getIpNumber(locHost); if (ipNumber == -1) { throw new IOException("Invalid host"); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -