/** * Handle the socket as a SEND. * * @return false when socket is closed (or should be closed), true will cause the method to be * called again. */ protected boolean handleSend() { try { final byte[] data = new byte[blockSize]; final int bytesRead = fileIn.read(data); readSize += bytesRead; if (bytesRead > 0) { for (DCCTransferHandler handler : handlers.get(DCCTransferHandler.class)) { handler.dataTransferred(this, bytesRead); } out.write(data, 0, bytesRead); out.flush(); // Wait for acknowledgement packet. if (!turbo) { int bytesReceived; do { bytesReceived = in.readInt(); } while (readSize - bytesReceived > 0); } if (readSize == size) { fileIn.close(); // Process all the ack packets that may have been sent. // In true turbo dcc mode, none will have been sent and the socket // will just close, in fast-dcc mode all the acks will be here, // So keep reading acks until the socket closes (IOException) or we // have received all the acks. if (turbo) { int ack; do { try { ack = in.readInt(); } catch (IOException e) { break; } } while (ack > 0 && readSize - ack > 0); } return false; } return true; } else if (bytesRead < 0) { fileIn.close(); return true; } } catch (IOException e) { return false; } return false; }
@Override protected void socketOpened() { try { active = true; transferFile = new File(filename); if (transferType == TransferType.RECEIVE) { fileOut = new DataOutputStream( new FileOutputStream(transferFile.getAbsolutePath(), startpos > 0)); } out = new DataOutputStream(socket.getOutputStream()); in = new DataInputStream(socket.getInputStream()); for (DCCTransferHandler handler : handlers.get(DCCTransferHandler.class)) { handler.socketOpened(this); } } catch (IOException ioe) { socketClosed(); } }
@Override protected void socketClosed() { // Try to close both, even if one fails. StreamUtils.close(out); StreamUtils.close(in); out = null; in = null; for (DCCTransferHandler handler : handlers.get(DCCTransferHandler.class)) { handler.socketClosed(this); } // Try to delete empty files. if (transferType == TransferType.RECEIVE && transferFile != null && transferFile.length() == 0) { transferFile.delete(); } synchronized (TRANSFERS) { TRANSFERS.remove(this); } active = false; }
/** * Handle the socket as a RECEIVE. * * @return false when socket is closed (or should be closed), true will cause the method to be * called again. */ protected boolean handleReceive() { try { final byte[] data = new byte[blockSize]; final int bytesRead = in.read(data); readSize += bytesRead; if (bytesRead > 0) { for (DCCTransferHandler handler : handlers.get(DCCTransferHandler.class)) { handler.dataTransferred(this, bytesRead); } fileOut.write(data, 0, bytesRead); if (!turbo) { // Send ack out.writeInt((int) readSize); out.flush(); } if (readSize == size) { fileOut.close(); if (turbo) { in.close(); } return false; } else { return true; } } else if (bytesRead < 0) { fileOut.close(); return false; } } catch (IOException e) { return false; } return false; }
/** * Change the handler for this DCC Send * * @param handler A class implementing DCCTransferHandler */ public void addHandler(final DCCTransferHandler handler) { handlers.add(DCCTransferHandler.class, handler); }