All Downloads are FREE. Search and download functionalities are using the official Maven repository.

eu.stratosphere.nephele.net.SocketInputStream Maven / Gradle / Ivy

There is a newer version: 0.5.2-hadoop2
Show newest version
/***********************************************************************************************************************
 * Copyright (C) 2010-2013 by the Stratosphere project (http://stratosphere.eu)
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
 * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations under the License.
 **********************************************************************************************************************/

/**
 * This file is based on source code from the Hadoop Project (http://hadoop.apache.org/), licensed by the Apache
 * Software Foundation (ASF) under the Apache License, Version 2.0. See the NOTICE file distributed with this work for
 * additional information regarding copyright ownership. 
 */

package eu.stratosphere.nephele.net;

import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.SelectableChannel;
import java.nio.channels.SelectionKey;

/**
 * This implements an input stream that can have a timeout while reading.
 * This sets non-blocking flag on the socket channel.
 * So after create this object, read() on {@link Socket#getInputStream()} and write() on
 * {@link Socket#getOutputStream()} for the associated socket will throw
 * IllegalBlockingModeException.
 * Please use {@link SocketOutputStream} for writing.
 */
public class SocketInputStream extends InputStream implements ReadableByteChannel {

	private Reader reader;

	private static class Reader extends SocketIOWithTimeout {
		ReadableByteChannel channel;

		Reader(ReadableByteChannel channel, long timeout)
															throws IOException {
			super((SelectableChannel) channel, timeout);
			this.channel = channel;
		}

		int performIO(ByteBuffer buf) throws IOException {
			return channel.read(buf);
		}
	}

	/**
	 * Create a new input stream with the given timeout. If the timeout
	 * is zero, it will be treated as infinite timeout. The socket's
	 * channel will be configured to be non-blocking.
	 * 
	 * @param channel
	 *        Channel for reading, should also be a {@link SelectableChannel}.
	 *        The channel will be configured to be non-blocking.
	 * @param timeout
	 *        timeout in milliseconds. must not be negative.
	 * @throws IOException
	 */
	public SocketInputStream(ReadableByteChannel channel, long timeout)
																		throws IOException {
		SocketIOWithTimeout.checkChannelValidity(channel);
		reader = new Reader(channel, timeout);
	}

	/**
	 * Same as SocketInputStream(socket.getChannel(), timeout): 
*
* Create a new input stream with the given timeout. If the timeout * is zero, it will be treated as infinite timeout. The socket's * channel will be configured to be non-blocking. * * @see SocketInputStream#SocketInputStream(ReadableByteChannel, long) * @param socket * should have a channel associated with it. * @param timeout * timeout timeout in milliseconds. must not be negative. * @throws IOException */ public SocketInputStream(Socket socket, long timeout) throws IOException { this(socket.getChannel(), timeout); } /** * Same as SocketInputStream(socket.getChannel(), socket.getSoTimeout()) * :
*
* Create a new input stream with the given timeout. If the timeout * is zero, it will be treated as infinite timeout. The socket's * channel will be configured to be non-blocking. * * @see SocketInputStream#SocketInputStream(ReadableByteChannel, long) * @param socket * should have a channel associated with it. * @throws IOException */ public SocketInputStream(Socket socket) throws IOException { this(socket.getChannel(), socket.getSoTimeout()); } @Override public int read() throws IOException { /* * Allocation can be removed if required. * probably no need to optimize or encourage single byte read. */ byte[] buf = new byte[1]; int ret = read(buf, 0, 1); if (ret > 0) { return (byte) buf[0]; } if (ret != -1) { // unexpected throw new IOException("Could not read from stream"); } return ret; } public int read(byte[] b, int off, int len) throws IOException { return read(ByteBuffer.wrap(b, off, len)); } public synchronized void close() throws IOException { /* * close the channel since Socket.getInputStream().close() * closes the socket. */ reader.channel.close(); reader.close(); } /** * Returns underlying channel used by inputstream. * This is useful in certain cases like channel for * {@link FileChannel#transferFrom(ReadableByteChannel, long, long)}. */ public ReadableByteChannel getChannel() { return reader.channel; } // ReadableByteChannel interface public boolean isOpen() { return reader.isOpen(); } public int read(ByteBuffer dst) throws IOException { return reader.doIO(dst, SelectionKey.OP_READ); } /** * waits for the underlying channel to be ready for reading. * The timeout specified for this stream applies to this wait. * * @throws SocketTimeoutException * if select on the channel times out. * @throws IOException * if any other I/O error occurs. */ public void waitForReadable() throws IOException { reader.waitForIO(SelectionKey.OP_READ); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy