Skip to content
This repository has been archived by the owner on Sep 9, 2021. It is now read-only.

Белов Егор, 3530901/70201 lab2s #34

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
232 changes: 60 additions & 172 deletions README.md

Large diffs are not rendered by default.

95 changes: 95 additions & 0 deletions src/ReadRequest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import java.net.*;
import java.io.*;


class ReadRequest extends Thread {

protected DatagramSocket socket;
protected InetAddress host;
protected int port;
protected FileInputStream source;
protected TftpPacket req;
protected int timeoutLimit = 5;
protected String fileName;

public ReadRequest(ReadPacket request) {
try {
req = request;
socket = new DatagramSocket();
socket.setSoTimeout(1000);
fileName = request.fileName();

host = request.getAddress();
port = request.getPort();

File srcFile = new File("../storage/" + fileName);
System.out.println("procce checking");
if (srcFile.exists() && srcFile.isFile() && srcFile.canRead()) {
source = new FileInputStream(srcFile);
this.start();
} else
throw new TftpException("access violation");

} catch (Exception e) {
ErrorPacket errorPacket = new ErrorPacket(1, e.getMessage());
try {
errorPacket.send(host, port, socket);
} catch (Exception e2) {
System.out.println(e2.toString());
}

System.out.println("Client start failed: " + e.getMessage());
}
}

public void run() {
int bytesRead = TftpPacket.maxTftpPakLen;
if (req instanceof ReadPacket) {
try {
for (int blkNum = 1; bytesRead == TftpPacket.maxTftpPakLen; blkNum++) {
DataPacket outPak = new DataPacket(blkNum, source);
System.out.println("send block no. " + outPak.blockNumber());
bytesRead = outPak.getLength();
System.out.println("bytes sent: " + bytesRead);
outPak.send(host, port, socket);
System.out.println("current op code " + outPak.get(0));

while (timeoutLimit != 0) {
try {
TftpPacket ack = TftpPacket.receive(socket);
if (!(ack instanceof AckPacket)) {
throw new Exception("Client failed");
}
AckPacket a = (AckPacket) ack;

if (a.blockNumber() != blkNum) { //check ack
throw new SocketTimeoutException("last packet lost, resend packet");
}
System.out.println("confirm blk num " + a.blockNumber() + " from " + a.getPort());
break;
} catch (SocketTimeoutException t) {//resend last packet
System.out.println("Resent blk " + blkNum);
timeoutLimit--;
outPak.send(host, port, socket);
}
}
if (timeoutLimit == 0) {
throw new Exception("connection failed");
}
}
System.out.println("Transfer completed.(Client " + host + ")");
System.out.println("Filename: " + fileName + "\nSHA1 checksum: " + SumHelper.getChecksum("../storage/" + fileName) + "\n");
} catch (Exception e) {
ErrorPacket ePak = new ErrorPacket(1, e.getMessage());

try {
ePak.send(host, port, socket);
} catch (Exception e2) {
System.out.println(e2.toString());
}

System.out.println("Client failed: " + e.getMessage());
}
}
}
}
32 changes: 32 additions & 0 deletions src/SumHelper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import java.io.FileInputStream;
import java.security.MessageDigest;


public class SumHelper {
static String getChecksum(String fileName) {
StringBuilder sb = new StringBuilder();
try {
MessageDigest md = MessageDigest.getInstance("SHA1");
FileInputStream fis = new FileInputStream(fileName);
byte[] dataBytes = new byte[1024];

int nread = 0;

while ((nread = fis.read(dataBytes)) != -1) {
md.update(dataBytes, 0, nread);
}
fis.close();

byte[] mdBytes = md.digest();

for (byte mdByte : mdBytes) {
sb.append(Integer.toString((mdByte & 0xff) + 0x100, 16).substring(1));
}

} catch (Exception e) {
System.out.println("Generate Checksum Failed: " + e.getMessage());
}

return sb.toString();
}
}
218 changes: 218 additions & 0 deletions src/TftpPacket.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,218 @@
import java.net.*;
import java.io.*;

class TftpException extends Exception {
public TftpException(String s) {
super(s);
}
}

public class TftpPacket {

// Tftp constants
public static int maxTftpPakLen = 516;
public static int maxTftpData = 512;

// Tftp opcodes
protected static final short tftpRRQ = 1;
protected static final short tftpWRQ = 2;
protected static final short tftpDATA = 3;
protected static final short tftpACK = 4;
protected static final short tftpERROR = 5;

// Packet Offsets
protected static final int opOffset = 0;

protected static final int fileOffset = 2;

protected static final int blkOffset = 2;
protected static final int dataOffset = 4;

protected static final int numOffset = 2;
protected static final int msgOffset = 4;

// The actual packet for UDP transfer
protected byte[] message;
protected int length;

protected InetAddress host;
protected int port;

public TftpPacket() {
message = new byte[maxTftpPakLen];
length = maxTftpPakLen;
}

public static TftpPacket receive(DatagramSocket sock) throws IOException {
TftpPacket in = new TftpPacket(), retPak = new TftpPacket();

DatagramPacket inPak = new DatagramPacket(in.message, in.length);
sock.receive(inPak);

switch (in.get(0)) {
case tftpRRQ:
retPak = new ReadPacket();
break;
case tftpWRQ:
retPak = new WritePacket();
break;
case tftpDATA:
retPak = new DataPacket();
break;
case tftpACK:
retPak = new AckPacket();
break;
case tftpERROR:
retPak = new ErrorPacket();
break;
}
retPak.message = in.message;
retPak.length = inPak.getLength();
retPak.host = inPak.getAddress();
retPak.port = inPak.getPort();

return retPak;
}

public void send(InetAddress ip, int port, DatagramSocket s) throws IOException {
s.send(new DatagramPacket(message, length, ip, port));
}

public InetAddress getAddress() {
return host;
}

public int getPort() {
return port;
}

public int getLength() {
return length;
}

protected void put(int at, short value) {
message[at++] = (byte) (value >>> 8);
message[at] = (byte) (value % 256);
}

protected void put(int at, String value, byte del) {
value.getBytes(0, value.length(), message, at);
message[at + value.length()] = del;
}

protected int get(int at) {
return (message[at] & 0xff) << 8 | message[at + 1] & 0xff;
}

protected String get(int at, byte del) {
StringBuilder result = new StringBuilder();
while (message[at] != del) result.append((char) message[at++]);
return result.toString();
}
}

final class DataPacket extends TftpPacket {

protected DataPacket() {
}

public DataPacket(int blockNumber, FileInputStream in) throws IOException {
this.message = new byte[maxTftpPakLen];
this.put(opOffset, tftpDATA);
this.put(blkOffset, (short) blockNumber);
length = in.read(message, dataOffset, maxTftpData) + 4;
}

public int blockNumber() {
return this.get(blkOffset);
}

public int write(FileOutputStream out) throws IOException {
out.write(message, dataOffset, length - 4);

return (length - 4);
}
}

class ErrorPacket extends TftpPacket {

protected ErrorPacket() {
}

public ErrorPacket(int number, String message) {
length = 4 + message.length() + 1;
this.message = new byte[length];
put(opOffset, tftpERROR);
put(numOffset, (short) number);
put(msgOffset, message, (byte) 0);
}

public String message() {
return this.get(msgOffset, (byte) 0);
}
}

final class AckPacket extends TftpPacket {

protected AckPacket() {
}

public AckPacket(int blockNumber) {
length = 4;
this.message = new byte[length];
put(opOffset, tftpACK);
put(blkOffset, (short) blockNumber);
}

public int blockNumber() {
return this.get(blkOffset);
}
}

final class ReadPacket extends TftpPacket {

protected ReadPacket() {
}

public ReadPacket(String filename, String dataMode) {
length = 2 + filename.length() + 1 + dataMode.length() + 1;
message = new byte[length];

put(opOffset, tftpRRQ);
put(fileOffset, filename, (byte) 0);
put(fileOffset + filename.length() + 1, dataMode, (byte) 0);
}

public String fileName() {
return this.get(fileOffset, (byte) 0);
}

// public String requestType() {
// String fname = fileName();
// return this.get(fileOffset + fname.length() + 1, (byte) 0);
// }
}

final class WritePacket extends TftpPacket {

protected WritePacket() {
}

// public WritePacket(String filename, String dataMode) {
// length = 2 + filename.length() + 1 + dataMode.length() + 1;
// message = new byte[length];
//
// put(opOffset, tftpWRQ);
// put(fileOffset, filename, (byte) 0);
// put(fileOffset + filename.length() + 1, dataMode, (byte) 0);
// }

public String fileName() {
return this.get(fileOffset, (byte) 0);
}

public String requestType() {
String fileName = fileName();
return this.get(fileOffset + fileName.length() + 1, (byte) 0);
}
}
Loading