X-Git-Url: https://git.pterodactylus.net/?a=blobdiff_plain;f=src%2Fmain%2Fjava%2Fnet%2Fpterodactylus%2Firc%2FDccReceiver.java;h=e024d4e68cad4cfd635c34e3d53f7836996d9181;hb=f724f1d4c327876f6a296a976b58e413c1eaaed6;hp=5c5eac4f6828568e37ffd25dd214e9900ac5ebfc;hpb=8e95f6d5936b720c056042e07d6db4bc3c9a026d;p=xudocci.git diff --git a/src/main/java/net/pterodactylus/irc/DccReceiver.java b/src/main/java/net/pterodactylus/irc/DccReceiver.java index 5c5eac4..e024d4e 100644 --- a/src/main/java/net/pterodactylus/irc/DccReceiver.java +++ b/src/main/java/net/pterodactylus/irc/DccReceiver.java @@ -23,14 +23,16 @@ import java.io.OutputStream; import java.net.InetAddress; import java.net.Socket; import java.util.concurrent.TimeUnit; -import java.util.logging.Level; -import java.util.logging.Logger; +import net.pterodactylus.irc.event.DccDownloadFailed; +import net.pterodactylus.irc.event.DccDownloadFinished; import net.pterodactylus.irc.event.DccSendReceived; import net.pterodactylus.xdcc.util.io.BandwidthCountingInputStream; +import com.google.common.eventbus.EventBus; import com.google.common.io.Closeables; import com.google.common.util.concurrent.AbstractExecutionThreadService; +import org.apache.log4j.Logger; /** * Service that receives a file offered by a {@link DccSendReceived}. @@ -42,6 +44,9 @@ public class DccReceiver extends AbstractExecutionThreadService { /** The logger. */ private static final Logger logger = Logger.getLogger(DccReceiver.class.getName()); + /** The event bus. */ + private final EventBus eventBus; + /** The address to connect to. */ private final InetAddress inetAddress; @@ -78,10 +83,33 @@ public class DccReceiver extends AbstractExecutionThreadService { * @param outputStream * The output stream to write the file to */ - public DccReceiver(InetAddress inetAddress, int port, String filename, long size, OutputStream outputStream) { + public DccReceiver(EventBus eventBus, InetAddress inetAddress, int port, String filename, long size, OutputStream outputStream) { + this(eventBus, inetAddress, port, filename, 0, size, outputStream); + } + + /** + * Creates a new DCC receiver. + * + * @param inetAddress + * The address to connect to + * @param port + * The port number to connect to + * @param filename + * The name of the file being downloaded + * @param startOffset + * The offset at which the download starts in case of a resume + * @param size + * The size of the file being downloaded, or {@code -1} if the size is not + * known + * @param outputStream + * The output stream to write the file to + */ + public DccReceiver(EventBus eventBus, InetAddress inetAddress, int port, String filename, long startOffset, long size, OutputStream outputStream) { + this.eventBus = eventBus; this.inetAddress = inetAddress; this.port = port; this.filename = filename; + this.progress = startOffset; this.size = size; this.outputStream = outputStream; } @@ -125,8 +153,8 @@ public class DccReceiver extends AbstractExecutionThreadService { * * @return The current rate of the download, in bytes/second */ - public long getCurrentRate() { - return inputStream.getCurrentRate(); + public long currentRate() { + return (inputStream != null) ? inputStream.getCurrentRate() : 0; } /** @@ -134,8 +162,8 @@ public class DccReceiver extends AbstractExecutionThreadService { * * @return The overall rate of the download, in bytes/second */ - public long getOverallRate() { - return inputStream.getOverallRate(); + public long overallRate() { + return (inputStream != null) ? inputStream.getOverallRate() : 0; } // @@ -147,6 +175,7 @@ public class DccReceiver extends AbstractExecutionThreadService { Socket socket = null; try { socket = new Socket(inetAddress, port); + socket.setSoTimeout((int) TimeUnit.MINUTES.toMillis(3)); InputStream socketInputStream = socket.getInputStream(); inputStream = new BandwidthCountingInputStream(socketInputStream, 5, TimeUnit.SECONDS); byte[] buffer = new byte[65536]; @@ -159,11 +188,20 @@ public class DccReceiver extends AbstractExecutionThreadService { outputStream.write(buffer, 0, r); progress += r; } + outputStream.flush(); + if ((size == -1) || (progress == size)) { + eventBus.post(new DccDownloadFinished(this)); + } else { + eventBus.post(new DccDownloadFailed(this, new IOException("Download aborted."))); + } } catch (IOException ioe1) { - logger.log(Level.WARNING, "I/O error while receiving DCC!", ioe1); + logger.warn("I/O error while receiving DCC!", ioe1); + eventBus.post(new DccDownloadFailed(this, ioe1)); } finally { Closeables.close(inputStream, true); - socket.close(); + if (socket != null) { + socket.close(); + } } }