datagramsocketcommclient.java

来自「cqME :java framework for TCK test.」· Java 代码 · 共 330 行

JAVA
330
字号
/* * $Id$ * * Copyright 1996-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.tck.j2me.services.commService.clients;import java.io.IOException;import java.io.DataInputStream;import java.io.DataOutputStream;import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.net.DatagramSocket;import java.net.DatagramPacket;import java.net.InetAddress;import com.sun.tck.j2me.communication.CommunicationClient;import com.sun.tck.j2me.services.commService.DatagramSocketCommServiceUtils;/** * DatagramSocket based DTF Communication Client for CDC/J2SE, with  * limited send and receive capability. */public class DatagramSocketCommClient extends DatagramSocketCommServiceUtils implements CommunicationClient {    protected static final int DEFAULT_CLIENT_NUM_OF_RETRIES = 12;    protected static final String NUM_OF_RETRIES_OPTION = "numberOfRetries=";    protected static final String PORT_TO_BIND_OPTION = "portToBind=";    private InetAddress serverAddress;    private String serverHost;    private int serverPort;    private String connID = "";    private int connIDBytesLength = 0;    private int packetNum = 0;    private int numOfRetries = DEFAULT_CLIENT_NUM_OF_RETRIES;    private int portToBind = 0; // Bind to any free port    public DatagramSocketCommClient() {        verboseln("Constructed new DatagramSocketCommClient");    }    public void init(String serverLocator, String connID, String[] args) {        this.connID = connID;                // reset server address        serverAddress = null;        decodeAllArgs(args);        verboseln("DatagramSocketCommClient.init serverLocator " + serverLocator);        verboseln("DatagramSocketCommClient.init connID " + connID);        ByteArrayOutputStream baos = new ByteArrayOutputStream();        DataOutputStream dos = new DataOutputStream(baos);        try {            dos.writeUTF(connID);            dos.close();            connIDBytesLength = dos.size();        } catch (IOException ioe) {            verbosetrace(ioe);            throw new IllegalArgumentException("DatagramSocketCommClient.init: " +                                               "failed to calculate length of " +                                               "connID converted to " +                                               "byte array due to " + ioe);        }        String[] hostport = getHostAndPortFromURL(serverLocator);        serverHost = hostport[0];        String serverPortString = hostport[1];        serverPort = -1;        try {            serverPort = Integer.parseInt(serverPortString);        } catch (NumberFormatException nfe) {            throw new IllegalArgumentException("DatagramSocketCommClient.init: " +                                               "invalid serverLocator " +                                                serverLocator + " " + nfe);        }        verboseln("DatagramSocketCommClient.init: host " + serverHost);        verboseln("DatagramSocketCommClient.init: port " + serverPort);    }    protected void processArg(String arg) {        if (arg.startsWith(NUM_OF_RETRIES_OPTION) && arg.length() > NUM_OF_RETRIES_OPTION.length()) {            String numOfRetriesString = arg.substring(NUM_OF_RETRIES_OPTION.length());            try {                numOfRetries = Integer.parseInt(numOfRetriesString);                if (numOfRetries < 1) {                    throw new IllegalArgumentException("Incorrect number of " +                                                       "retries specified: " +                                                       numOfRetriesString);                }            } catch (NumberFormatException nfe) {                throw new IllegalArgumentException("Incorrect number of " +                                                   "retries specified: " +                                                   numOfRetriesString);            }        } else if (arg.startsWith(PORT_TO_BIND_OPTION) && arg.length() > PORT_TO_BIND_OPTION.length()) {            String portToBindString = arg.substring(PORT_TO_BIND_OPTION.length());            try {                portToBind = Integer.parseInt(portToBindString);                if (numOfRetries < 0) {                    throw new IllegalArgumentException("Incorrect port to " +                                                       "bind specified: " +                                                       portToBindString);                }            } catch (NumberFormatException nfe) {                throw new IllegalArgumentException("Incorrect port to " +                                                   "bind specified: " +                                                   portToBindString);            }        } else {            super.processArg(arg);        }    }    public synchronized byte[] send(byte[] packet) throws IOException {        if (packet == null)            throw new IllegalArgumentException(                    "DatagramSocketCommClient: Attempt to send null packet.");                if (packet.length > getSendLimitSize()) {            throw new IllegalArgumentException(                    "DatagramSocketCommClient: Attempt to send"                            + " an oversized packet.");        }                if (serverAddress == null) {            serverAddress = InetAddress.getByName(serverHost);        }        ByteArrayOutputStream baos = new ByteArrayOutputStream();        DataOutputStream dos = new DataOutputStream(baos);        // prepare DatagramPacket to be sent        // first 4 bytes is packet number        dos.writeInt(packetNum);        // write connID        dos.writeUTF(connID);        // write data        dos.write(packet, 0, packet.length);        dos.close();        byte[] buf = baos.toByteArray();        DatagramPacket packetToSend = new DatagramPacket(buf, buf.length,                serverAddress, serverPort);        // prepare DatagramPacket to be received        byte[] buf2 = new byte[packetSize];        DatagramPacket packetToReceive = new DatagramPacket(buf2, buf2.length);        DatagramSocket dts = null;        try {            // The following is equivalent to DatagramSocket(0), but            // DatagramSocket(int port) specification does not specify behavior when            // port is 0. Replace it by DatagramSocket() to be safe.            //            // dts = new DatagramSocket(portToBind);            // create a DatagramSocket which binds to a system chosen port            dts = new DatagramSocket();            dts.setSoTimeout(socketTimeout);            int rcvBufSz = dts.getReceiveBufferSize();            int sndBufSz = dts.getSendBufferSize();            verboseln("DatagramSocketCommClient.send: created socket");            verboseln("DatagramSocketCommClient.send: socket's local address " + dts.getLocalAddress());            verboseln("DatagramSocketCommClient.send: socket's receive buffer " + rcvBufSz);            verboseln("DatagramSocketCommClient.send: socket's send buffer " + sndBufSz);            if (rcvBufSz < (packetSize + 28) || sndBufSz < (packetSize + 28)) {                verboseln("Warning size of buffers might be not enough: " +                          "Receive - " + rcvBufSz + ", Send - " + sndBufSz);            }            for (int numAttempts = 0; numAttempts < numOfRetries; numAttempts++) {                try {                    verboseln("Sending packet number " + packetNum + " to " +                               packetToSend.getAddress());                    dts.send(packetToSend);                } catch (IOException ioe) {                    verboseln("IOException in send" + ioe);                    continue;                }                // This while is needed to read all available datagrams                // before resending data. Server is passive, it only sends                // one datagram in response to every received datagram.                while (true) {                    try {                        packetToReceive.setLength(packetSize);                        dts.receive(packetToReceive);                        verboseln("Got out of dts.receive(packetToReceive)");                    } catch (IOException ioe) {                        verboseln("IOException in receive " + ioe);                        break;                    }                    InetAddress senderAddress = packetToReceive.getAddress();                    verboseln("Received packet from " + senderAddress);                    byte[] data = packetToReceive.getData();                    if (data.length < 4) {                        verboseln("Panic, packet's data length is " + data.length);                        continue;                    }                    // need to take length of Datagram into account because                    // getData() returns NOT the content of the datagram,                     // but rather the whole buffer                    ByteArrayInputStream bais = new ByteArrayInputStream(                            data,                            packetToReceive.getOffset(),                            packetToReceive.getLength());                    DataInputStream dis = new DataInputStream(bais);                    int receivedPacketNum = dis.readInt();                    verboseln("Number of received packet is " + receivedPacketNum);                    if (receivedPacketNum == packetNum) {                        byte[] ret = new byte[dis.available()];                        dis.readFully(ret);                        return ret;                    } else {                        verboseln("WARNING: Received packet has unexpected number " + receivedPacketNum + ", expected " + packetNum);                    }                }            }            throw new IOException("Failed to send packet " +                                   numOfRetries + " times.");        } finally {            packetNum++;            if (dts != null) {                dts.close();            }            verboseln("End of send's finally");        }    }    public int getSendLimitSize() {        return packetSize - 4 - connIDBytesLength;    }    public int getRcvLimitSize() {        return packetSize - 4 - connIDBytesLength;    }    private static String[] getHostAndPortFromURL(String url)             throws IllegalArgumentException {        // parse url into hostname and port        // expecting something like http://host:port or         // datagram://host:port. Class URL can not parse neither        // http://host:port nor datagram://host:port under CDC. Class        // URI is not available under CDC so parse manually.        int pos = url.indexOf("://");        int pos2 = url.lastIndexOf(":", url.length() - 1);        if (pos == -1 || pos2 == -1 || pos2 == url.length() - 1 ||                 pos2 <= pos + 3 || url.indexOf(']') > pos2) {            throw new IllegalArgumentException("Cannot determine host and/or "                    + "port from URL " + url );        }        try {            String hostpart = url.substring(pos + 3, pos2);            String portpart = url.substring(pos2 + 1);            if (hostpart.startsWith("[")) {                // This is an RFC 2732 address                int pos3 = hostpart.indexOf(']');                hostpart = hostpart.substring(1, pos3);            }            return new String[] {hostpart, portpart};        } catch (IndexOutOfBoundsException e) {            throw new IllegalArgumentException("Errors occurs when parsing URL "                + url + " : " + e.getMessage());        }    }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?