KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > rero > dcc > Receive


1 /*
2     jerk.irc.dcc.ChatClient [ created - 1/2/02 ]
3
4     Author: Raphael Mudge (rsmudge@mtu.edu)
5     
6     Description:
7     handles the details of talking in a DCC connection, nothing to do
8     with actually establishing the connection. Talks to a JerkEngine
9     reference.
10
11     Documentation:
12     n/a
13
14     Changelog:
15        
16 */

17
18 package rero.dcc;
19
20 import java.util.*;
21
22 import java.net.*;
23 import java.io.*;
24
25 import rero.ircfw.*;
26 import rero.ircfw.interfaces.*;
27
28 public class Receive extends ProtocolDCC
29 {
30     protected static int PACKET_SIZE = 4096;
31
32     protected File dumpTo;
33     protected FileOutputStream fileStream;
34
35     protected long receivedSize;
36     protected long finalSize;
37     protected long startSize; // number of bytes we started out with, so resumes don't throw off rate calculations
38

39     /**
40      * Create a ready to rock and roll receive socket. It is assumed that the File object is either cleared
41      * or ready to be resumed. An overwrite command should delete the file first and then start dumping to it.
42      * Hopefully this is a safe way to go. Eh?
43      */

44     public Receive(String JavaDoc _nickname, File _dumpTo, long _finalSize)
45     {
46        nickname = _nickname;
47        dumpTo = _dumpTo;
48        finalSize = _finalSize;
49
50        receivedSize = 0;
51        startSize = 0;
52     }
53
54     /** return the number of bytes that have been received thus far */
55     public long getBytesReceived()
56     {
57        return receivedSize;
58     }
59
60     /** return the expected size of the file we are receiving */
61     public long getExpectedSize()
62     {
63        return finalSize;
64     }
65  
66     /** return the object pointing to the File we are downloading */
67     public File getFile()
68     {
69        return dumpTo;
70     }
71
72     /** return the estimated time remaning in seconds */
73     public long getTimeRemaining()
74     {
75        long toGo = getExpectedSize() - getFile().length();
76        long transferRate = (long)getTransferRate();
77
78        if (transferRate == 0)
79            transferRate = 1000;
80
81        return toGo / transferRate;
82     }
83
84     public void setFile(File f)
85     {
86        dumpTo = f;
87     }
88
89     public void pleaseResume()
90     {
91        receivedSize = dumpTo.length();
92        startSize = dumpTo.length();
93     }
94
95     /** return the number of bytes that we started out with (0 normally, however in the case of a resume this number could be
96         anything from 0 up to nearly the size of the file */

97     public long getStartOffset()
98     {
99        return startSize;
100     }
101
102     /** return the number of bytes transferred per second */
103     public int getTransferRate()
104     {
105        if (getTotalTime() < 1000)
106           return 1000;
107
108        return (int)( (getBytesReceived() - getStartOffset()) / (getTotalTime() / 1000));
109     }
110
111     public int getTypeOfDCC()
112     {
113        return DCC_RECEIVE;
114     }
115
116     public void run()
117     {
118        if (socket == null || !socket.isConnected())
119        {
120           return;
121        }
122
123        try
124        {
125           socket.setSoTimeout(DCC_TIMEOUT);
126        }
127        catch (Exception JavaDoc ex)
128        {
129           ex.printStackTrace();
130        }
131
132        // fire event that the receive has started..
133

134        fireEvent("RECEIVE_START", null);
135
136
137        startTime = System.currentTimeMillis();
138
139        InputStream istream = null;
140        OutputStream ostream = null;
141
142        byte[] data = new byte[PACKET_SIZE]; // read packets in 4k chunks
143
byte[] ackPacket = new byte[4];
144
145        Exception JavaDoc transferError = null;
146
147        try
148        {
149           boolean appendToFile = startSize != 0;
150
151           fileStream = new FileOutputStream(dumpTo, appendToFile);
152
153           istream = socket.getInputStream();
154           ostream = socket.getOutputStream();
155    
156           while (receivedSize < finalSize && socket.isConnected())
157           {
158               int thisRead;
159        
160               if ( (finalSize - receivedSize) < PACKET_SIZE )
161               {
162                  thisRead = istream.read(data, 0, (int) (finalSize - receivedSize) );
163               }
164               else
165               {
166                  thisRead = istream.read(data, 0, PACKET_SIZE);
167               }
168
169               if (thisRead > 0)
170               {
171                  fileStream.write(data, 0, thisRead);
172              
173                  receivedSize += thisRead;
174   
175                // System.out.println("Read in: " + thisRead + " bytes");
176

177                  //
178
// write acknowledgement packet to the output stream (for fun and profit)
179
//
180
ackPacket[0] = (byte) ( ((receivedSize & 0xff000000) >> 24) | 0 );
181                  ackPacket[1] = (byte) ( ((receivedSize & 0x00ff0000) >> 16) | 0 );
182                  ackPacket[2] = (byte) ( ((receivedSize & 0x0000ff00) >> 8 ) | 0 );
183                  ackPacket[3] = (byte) ( ((receivedSize & 0x000000ff) >> 0 ) | 0 );
184                
185                 // System.out.println("Writing ACK Packet: " + ackPacket);
186
// System.out.println("Received Size : " + receivedSize);
187

188                  ostream.write(ackPacket, 0, 4);
189                  ostream.flush();
190               }
191           }
192        }
193        catch (Exception JavaDoc ex)
194        {
195           if (receivedSize != finalSize)
196           {
197               ex.printStackTrace();
198               transferError = ex;
199           }
200        }
201
202        try
203        {
204           fileStream.close();
205        }
206        catch (Exception JavaDoc ex)
207        {
208           ex.printStackTrace();
209        }
210
211        if (receivedSize == finalSize)
212        {
213           //
214
// dispatch the send succeeded event
215
//
216
fireEvent("RECEIVE_COMPLETE", null);
217        }
218        else if (transferError != null)
219        {
220           fireError(transferError.getMessage());
221        }
222        else
223        {
224           fireError("incomplete");
225        }
226     }
227
228     public void fireEvent(String JavaDoc event, String JavaDoc description)
229     {
230        eventData.put(FrameworkConstants.$NICK$, getNickname());
231        eventData.put(FrameworkConstants.$EVENT$, event);
232        eventData.put(FrameworkConstants.$DATA$, getNickname() + " " + description);
233        eventData.put(FrameworkConstants.$PARMS$, description);
234        eventData.put("$this", this.toString());
235
236        dispatcher.dispatchEvent(eventData);
237     }
238
239     public void fireError(String JavaDoc description)
240     {
241        eventData.put(FrameworkConstants.$NICK$, getNickname());
242        eventData.put(FrameworkConstants.$EVENT$, "RECEIVE_FAILED");
243        eventData.put(FrameworkConstants.$DATA$, getNickname() + " " + description);
244        eventData.put(FrameworkConstants.$PARMS$, description);
245        eventData.put("$this", this.toString());
246
247        dispatcher.dispatchEvent(eventData);
248     }
249 }
250
Popular Tags