001: /*
002: * Portions Copyright 2000-2003 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: /*
027: * @(#)TCPClient.java 1.15 07/05/05
028: *
029: * (C) Copyright IBM Corp. 1999 All Rights Reserved.
030: * Copyright 1997 The Open Group Research Institute. All rights reserved.
031: */
032:
033: package sun.security.krb5.internal;
034:
035: import java.io.*;
036: import java.net.*;
037:
038: public class TCPClient {
039:
040: private Socket tcpSocket;
041: private BufferedOutputStream out;
042: private BufferedInputStream in;
043:
044: public TCPClient(String hostname, int port) throws IOException {
045: tcpSocket = new Socket(hostname, port);
046: out = new BufferedOutputStream(tcpSocket.getOutputStream());
047: in = new BufferedInputStream(tcpSocket.getInputStream());
048: }
049:
050: public void send(byte[] data) throws IOException {
051: byte[] lenField = new byte[4];
052: intToNetworkByteOrder(data.length, lenField, 0, 4);
053: out.write(lenField);
054:
055: out.write(data);
056: out.flush();
057: }
058:
059: public byte[] receive() throws IOException {
060: byte[] lenField = new byte[4];
061: int count = readFully(lenField, 4);
062:
063: if (count != 4) {
064: if (Krb5.DEBUG) {
065: System.out
066: .println(">>>DEBUG: TCPClient could not read length field");
067: }
068: return null;
069: }
070:
071: int len = networkByteOrderToInt(lenField, 0, 4);
072: if (Krb5.DEBUG) {
073: System.out.println(">>>DEBUG: TCPClient reading " + len
074: + " bytes");
075: }
076: if (len <= 0) {
077: if (Krb5.DEBUG) {
078: System.out
079: .println(">>>DEBUG: TCPClient zero or negative length field: "
080: + len);
081: }
082: return null;
083: }
084:
085: byte data[] = new byte[len];
086: count = readFully(data, len);
087: if (count != len) {
088: if (Krb5.DEBUG) {
089: System.out
090: .println(">>>DEBUG: TCPClient could not read complete packet ("
091: + len + "/" + count + ")");
092: }
093: return null;
094: } else {
095: return data;
096: }
097: }
098:
099: public void close() throws IOException {
100: tcpSocket.close();
101: }
102:
103: /**
104: * Read requested number of bytes before returning.
105: * @return The number of bytes actually read; -1 if none read
106: */
107: private int readFully(byte[] inBuf, int total) throws IOException {
108: int count, pos = 0;
109:
110: while (total > 0) {
111: count = in.read(inBuf, pos, total);
112:
113: if (count == -1) {
114: return (pos == 0 ? -1 : pos);
115: }
116: pos += count;
117: total -= count;
118: }
119: return pos;
120: }
121:
122: /**
123: * Returns the integer represented by 4 bytes in network byte order.
124: */
125: private static final int networkByteOrderToInt(byte[] buf,
126: int start, int count) {
127: if (count > 4) {
128: throw new IllegalArgumentException(
129: "Cannot handle more than 4 bytes");
130: }
131:
132: int answer = 0;
133:
134: for (int i = 0; i < count; i++) {
135: answer <<= 8;
136: answer |= ((int) buf[start + i] & 0xff);
137: }
138: return answer;
139: }
140:
141: /**
142: * Encodes an integer into 4 bytes in network byte order in the buffer
143: * supplied.
144: */
145: private static final void intToNetworkByteOrder(int num,
146: byte[] buf, int start, int count) {
147: if (count > 4) {
148: throw new IllegalArgumentException(
149: "Cannot handle more than 4 bytes");
150: }
151:
152: for (int i = count - 1; i >= 0; i--) {
153: buf[start + i] = (byte) (num & 0xff);
154: num >>>= 8;
155: }
156: }
157: }
|