📄 protocol.java
字号:
/* * @(#)Protocol.java 1.52 02/10/14 @(#) * * Copyright (c) 1999-2002 Sun Microsystems, Inc. All rights reserved. * PROPRIETARY/CONFIDENTIAL * Use is subject to license terms. */package com.sun.midp.io.j2me.datagram;import java.io.*;import javax.microedition.io.*;import com.sun.cldc.io.ConnectionBaseInterface;import com.sun.cldc.io.GeneralBase;import com.sun.midp.io.*;import com.sun.midp.io.j2me.push.*;import com.sun.midp.midlet.*;import com.sun.midp.security.*;/** * This is the default "datagram://" protocol for J2ME that maps onto UDP. * * @author Nik Shaylor * @version 1.1 11/19/99 */public class Protocol implements UDPDatagramConnection, ConnectionBaseInterface { /** This class has a different security domain than the MIDlet suite */ private static SecurityToken classSecurityToken; /** Initialize the native network. */ static { NetworkConnectionBase.initializeNativeNetwork(); } /** * Initializes the security token for this class, so it can * perform actions that a normal MIDlet Suite cannot. * * @param token security token for this class. */ public static void initSecurityToken(SecurityToken token) { if (classSecurityToken != null) { return; } classSecurityToken = token; } /** Used by native code to hold the file descriptor handle. */ private int handle; /** 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; /** * 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 { int incommingPort = 0; Scheduler scheduler = Scheduler.getScheduler(); MIDletSuite midletSuite = scheduler.getMIDletSuite(); // 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"); } 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) { try { // When asking permission use Internet protocol name. midletSuite.checkForPermission(Permissions.UDP_SERVER, "UDP:" + name); } catch (SecurityException e) { // Give back the connection to AMS PushRegistryImpl.checkInConnectionInternal( classSecurityToken, "datagram:" + name); throw e; } catch (InterruptedException ie) { throw new InterruptedIOException( "Interrupted while trying to ask the user permission"); } if (port > 0) { incommingPort = port; } } else { if (port < 0) { throw new IllegalArgumentException("Missing port number"); } try { // When asking permission use Internet protocol name. midletSuite.checkForPermission(Permissions.UDP, "UDP:" + name); } catch (InterruptedException ie) { throw new InterruptedIOException( "Interrupted while trying to ask the user permission"); } } /* 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"); } String root = midletSuite.getStorageName(); byte[] asciiStorage = Util.toCString(root); open0(incommingPort, asciiStorage); registerCleanup(); open = true; return this; } /** * 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 { synchronized (dgram) { int length; int ipNumber; int port; 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"); } port = dh.port; } else { // address is a datagram url String addr; HttpUrl url; String host; addr = dgram.getAddress(); if (addr == null) { throw new IOException( "No address in datagram"); } url = new HttpUrl(addr); host = url.host; port = url.port; if (host == null) { throw new IOException("Missing host"); } if (port == -1) { throw new IOException("Missing port"); } ipNumber = getIpNumber(Util.toCString(host)); if (ipNumber == -1) { throw new IOException("Invalid host"); } } while (true) { int res; try { res = send0(ipNumber, port, dgram.getData(), dgram.getOffset(), length); } finally { if (!open) { throw new InterruptedIOException("Socket closed"); } } if (res == dgram.getLength()) { break; } if (res != 0) { throw new IOException("Failed to send datagram"); } /* Wait a while for I/O to become ready */ GeneralBase.iowait(); } } } /** * Receive a datagram. * * @param dgram a datagram * @exception IOException if an I/O error occurs */ public synchronized void receive(Datagram dgram) throws IOException { synchronized (dgram) { int length; long res; int count; int ipNumber; String host; int port; String addr; ensureOpen(); length = dgram.getLength(); if (length <= 0) { throw new IOException("Bad datagram length"); } while (true) { try { res = receive0(dgram.getData(), dgram.getOffset(),
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -