-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathFileSender.java
126 lines (102 loc) · 4.09 KB
/
FileSender.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
// Author: A0114171W
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketTimeoutException;
class FileSender {
String srcFileName, hostname, destFileName;
int portNo;
PacketHandler handler;
public static void main(String[] args) {
// check if the number of command line argument is 3
if (args.length != 3) {
System.out.println("Usage: java FileSender <path/filename> "
+ "<rcvPort> <rcvFileName>");
System.exit(1);
}
FileSender sender = new FileSender(args[0], "localhost", args[1], args[2]);
try {
sender.send();
System.out.println(args[0] + " is successfully sent as " + args[2]);
} catch (IOException | InterruptedException e) {
e.printStackTrace();
System.exit(1);
}
}
public FileSender(String fileToOpen, String host, String port,
String rcvFileName) {
srcFileName = fileToOpen;
hostname = host;
portNo = Integer.parseInt(port);
destFileName = rcvFileName;
handler = new PacketHandler();
}
void send() throws IOException, InterruptedException {
InetAddress rcvAddress = InetAddress.getByName(hostname);
DatagramSocket socket = new DatagramSocket();
socket.setSoTimeout(100);
byte[] dataBuffer = new byte[PacketHandler.MAX_PAYLOAD_LENGTH];
FileInputStream fis = new FileInputStream(srcFileName);
BufferedInputStream bis = new BufferedInputStream(fis);
int seqNo = setupConnection(rcvAddress, socket, destFileName);
int bytesRead;
while ((bytesRead = bis.read(dataBuffer)) > 0) {
byte[] outBuffer =
handler.createOutgoingPacket(dataBuffer, bytesRead, seqNo);
DatagramPacket pktOut =
new DatagramPacket(outBuffer, outBuffer.length, rcvAddress, portNo);
byte[] inBuffer = new byte[PacketHandler.MAX_PACKET_SIZE];
DatagramPacket pktIn = new DatagramPacket(inBuffer, inBuffer.length);
seqNo += bytesRead;
sendUntilReplied(socket, pktOut, pktIn, seqNo);
}
closeConnection(rcvAddress, socket, seqNo);
socket.close();
bis.close();
}
private void closeConnection(InetAddress rcvAddress, DatagramSocket socket,
int seqNo) throws IOException {
byte[] outBuffer =
handler.createFinPacket(seqNo);
DatagramPacket pktOut =
new DatagramPacket(outBuffer, outBuffer.length, rcvAddress, portNo);
byte[] inBuffer = new byte[PacketHandler.MAX_PACKET_SIZE];
DatagramPacket pktIn = new DatagramPacket(inBuffer, inBuffer.length);
sendUntilReplied(socket, pktOut, pktIn, seqNo);
}
private int setupConnection(InetAddress rcvAddress, DatagramSocket socket,
String fileName) throws IOException {
byte[] data = fileName.getBytes();
int seqNo = 0;
byte[] outBuffer =
handler.createSynPacket(data, data.length, seqNo);
DatagramPacket pktOut =
new DatagramPacket(outBuffer, outBuffer.length, rcvAddress, portNo);
byte[] inBuffer = new byte[PacketHandler.MAX_PACKET_SIZE];
DatagramPacket pktIn = new DatagramPacket(inBuffer, inBuffer.length);
seqNo += data.length;
sendUntilReplied(socket, pktOut, pktIn, seqNo);
return seqNo;
}
/**
* @param socket
* @param pktOut
* @param pktIn
* @param seqNo
* @throws IOException
*/
private void sendUntilReplied(DatagramSocket socket, DatagramPacket pktOut,
DatagramPacket pktIn, int seqNo) throws IOException {
do {
socket.send(pktOut);
try {
socket.receive(pktIn);
} catch (SocketTimeoutException e) {
continue;
}
} while (handler.isCorruptedReply(pktIn.getData(), seqNo));
}
}