/* * Project: xdccBee * Copyright (C) 2009 snert@snert-lab.de, * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * 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 for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package de.snertlab.xdccBee.irc; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.Socket; /** * @author snert * */ public class DccFileTransfer extends Thread { // TODO: Transfer Resume private Socket s; private InputStream in; private String host; private int port; private long size; private String filename; private String fullFilename; private long progress; private long fileSizeOnResume; private String nick; private long startTime; private boolean resume; public DccFileTransfer(String host, int port, long size, String nick, String filename, boolean resume) throws Exception { this.host = host; this.port = port; this.size = size; this.filename = filename; this.nick = nick; this.resume = resume; setDaemon(true); setPriority(Thread.MIN_PRIORITY); } /** * @deprecated Please now use start(String downloadDirFilename) * @see start(String downloadDirFilename) */ @Deprecated public synchronized void start() { super.start(); } public synchronized void start(String downloadDirFilename) { fullFilename = downloadDirFilename + filename; super.start(); } public void run() { try { openSocket(); } catch (Exception exc) { close(); throw new RuntimeException(exc.toString()); } } private void openSocket() throws IOException { close(); s = new Socket(host, port); s.setSoTimeout(1000 * 60 * 15); in = s.getInputStream(); ship(); } private void ship() throws IOException { BufferedOutputStream foutput = null; try { startTime = System.currentTimeMillis(); BufferedInputStream input = new BufferedInputStream( s.getInputStream()); BufferedOutputStream output = new BufferedOutputStream( s.getOutputStream()); if (resume) { File f = new File(fullFilename); progress = f.length(); fileSizeOnResume = progress; } foutput = new BufferedOutputStream(new FileOutputStream( fullFilename, resume)); byte[] inBuffer = new byte[1024]; byte[] outBuffer = new byte[4]; int bytesRead = 0; while (((bytesRead = input.read(inBuffer, 0, inBuffer.length)) != -1)) { foutput.write(inBuffer, 0, bytesRead); progress += bytesRead; // Send back an acknowledgement of how many bytes we have got so // far. outBuffer[0] = (byte) ((progress >> 24) & 0xff); outBuffer[1] = (byte) ((progress >> 16) & 0xff); outBuffer[2] = (byte) ((progress >> 8) & 0xff); outBuffer[3] = (byte) ((progress >> 0) & 0xff); output.write(outBuffer); output.flush(); } } catch (Exception e) { if (isInterrupted()) { // thread was interrupted => is ok was called // from close // nothing } else { // real error so throw throw new RuntimeException(e); } } finally { try { foutput.flush(); foutput.close(); close(); } catch (Exception anye) { // Do nothing. } } } public void close() { try { if (s != null) { if (!s.isClosed()) { s.close(); } } if (in != null) { in.close(); } } catch (Exception exc) { // nothing } interrupt(); } public String getNick() { return nick; } public long getProgress() { return progress; } public long getSize() { return size; } public long getTransferRate() { long time = (System.currentTimeMillis() - startTime) / 1000; if (time <= 0) { return 0; } if (resume) { return (getProgress() - fileSizeOnResume) / time; } return getProgress() / time; } public boolean isResume() { return resume; } public String getFilename() { return filename; } public int getPort() { return port; } }