Author: rwinston
Date: Sat Nov 11 08:09:00 2006
New Revision: 473744

URL: http://svn.apache.org/viewvc?view=rev&rev=473744
Log:
NET-68: TFTP client drops last packet

Modified:
    
jakarta/commons/proper/net/branches/JDK_1_5_BRANCH/src/main/java/org/apache/commons/net/tftp/TFTPClient.java

Modified: 
jakarta/commons/proper/net/branches/JDK_1_5_BRANCH/src/main/java/org/apache/commons/net/tftp/TFTPClient.java
URL: 
http://svn.apache.org/viewvc/jakarta/commons/proper/net/branches/JDK_1_5_BRANCH/src/main/java/org/apache/commons/net/tftp/TFTPClient.java?view=diff&rev=473744&r1=473743&r2=473744
==============================================================================
--- 
jakarta/commons/proper/net/branches/JDK_1_5_BRANCH/src/main/java/org/apache/commons/net/tftp/TFTPClient.java
 (original)
+++ 
jakarta/commons/proper/net/branches/JDK_1_5_BRANCH/src/main/java/org/apache/commons/net/tftp/TFTPClient.java
 Sat Nov 11 08:09:00 2006
@@ -22,7 +22,6 @@
 import java.net.InetAddress;
 import java.net.SocketException;
 import java.net.UnknownHostException;
-
 import org.apache.commons.net.io.FromNetASCIIOutputStream;
 import org.apache.commons.net.io.ToNetASCIIInputStream;
 
@@ -361,7 +360,7 @@
     public void sendFile(String filename, int mode, InputStream input,
                          InetAddress host, int port) throws IOException
     {
-        int bytesRead, timeouts, lastBlock, block, hostPort, dataLength, 
offset;
+        int bytesRead, timeouts, lastBlock, block, hostPort, dataLength, 
offset, totalThisPacket;
         TFTPPacket sent, received = null;
         TFTPErrorPacket error;
         TFTPDataPacket data =
@@ -369,10 +368,13 @@
         ;
         TFTPAckPacket ack;
 
+        boolean justStarted = true;
+        
         beginBufferedOps();
 
-        dataLength = lastBlock = hostPort = bytesRead = 0;
+        dataLength = lastBlock = hostPort = bytesRead = totalThisPacket = 0;
         block = 0;
+        boolean lastAckWait = false;
 
         if (mode == TFTP.ASCII_MODE)
             input = new ToNetASCIIInputStream(input);
@@ -383,11 +385,16 @@
 _sendPacket:
         do
         {
+            // first time: block is 0, lastBlock is 0, send a request packet.
+            // subsequent: block is integer starting at 1, send data packet.
             bufferedSend(sent);
-
+            
+            // this is trying to receive an ACK
 _receivePacket:
             while (true)
             {
+                
+
                 timeouts = 0;
                 while (timeouts < __maxTimeouts)
                 {
@@ -419,12 +426,13 @@
                         endBufferedOps();
                         throw new IOException("Bad packet: " + e.getMessage());
                     }
-                }
+                } // end of while loop over tries to receive
 
                 // The first time we receive we get the port number and
         // answering host address (for hosts with multiple IPs)
-                if (lastBlock == 0)
+                if (justStarted)
                 {
+                    justStarted = false;
                     hostPort = received.getPort();
                     data.setPort(hostPort);
                     if(!host.equals(received.getAddress()))
@@ -456,7 +464,13 @@
                         if (lastBlock == block)
                         {
                             ++block;
-                            break _receivePacket;
+                            if (lastAckWait) {
+                                
+                              break _sendPacket;
+                            }
+                            else {
+                              break _receivePacket;
+                            }
                         }
                         else
                         {
@@ -489,22 +503,33 @@
                 //break;
             }
 
+            // OK, we have just gotten ACK about the last data we sent. Make 
another
+            // and send it            
+
             dataLength = TFTPPacket.SEGMENT_SIZE;
             offset = 4;
+            totalThisPacket = 0;
             while (dataLength > 0 &&
                     (bytesRead = input.read(_sendBuffer, offset, dataLength)) 
> 0)
             {
                 offset += bytesRead;
                 dataLength -= bytesRead;
+                totalThisPacket += bytesRead;
             }
 
+            if( totalThisPacket < TFTPPacket.SEGMENT_SIZE ) {
+                /* this will be our last packet -- send, wait for ack, stop */
+                lastAckWait = true;
+            }
             data.setBlockNumber(block);
-            data.setData(_sendBuffer, 4, offset - 4);
+            data.setData(_sendBuffer, 4, totalThisPacket);
             sent = data;
         }
-        while (dataLength == 0);
-
-        bufferedSend(sent);
+        while ( totalThisPacket > 0 || lastAckWait );
+        // Note: this was looping while dataLength == 0 || lastAckWait,
+        // which was discarding the last packet if it was not full size
+        // Should send the packet. 
+        
         endBufferedOps();
     }
 



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to