Skip to content

Instantly share code, notes, and snippets.

@aurorapar
Created April 4, 2018 08:20
Show Gist options
  • Save aurorapar/99311d87d09afacd212e34c6b7448f0c to your computer and use it in GitHub Desktop.
Save aurorapar/99311d87d09afacd212e34c6b7448f0c to your computer and use it in GitHub Desktop.
// Client
import java.net.*;
import java.io.*;
import java.util.*;
import java.nio.charset.*;
public class Client
{
public static int serverPort = 69;
public static int blockNumber = 0;
public static String serverAddress = "10.20.73.179";
public static int timeouts = 0;
public static void main(String args[])
{
if(args.length != 2)
{
System.out.println("Improper argument length. Correct options are:\n\t[write|read] file");
return;
}
String operation = args[0].toLowerCase();
String fileName = args[1];
if(!"read".equals(operation) && !"write".equals(operation))
{
System.out.println(String.format("Could not handle \'operation\' %s\nAccepted operations are:\n\tread\twrite\n",operation));
return;
}
File f = new File(fileName);
if(!f.exists() || f.isDirectory())
{
System.out.println(String.format("Could not handle request\n\t%s\ndoes not exist", fileName));
return;
}
byte[] fileData;
FileInputStream fileStream;
int fileSize;
try
{
fileStream = new FileInputStream(f);
fileSize = fileStream.available();
System.out.println("Bytes to be sent:\n\t" + fileSize);
}
catch(Exception e)
{
debug(e.toString());
return;
}
byte OPCode;
if("read".equals(operation))
OPCode = 0x1;
else
{
OPCode = 0x2;
}
// Communications
byte[] receiveData = new byte[512];
try
{
ByteArrayOutputStream sendStream = new ByteArrayOutputStream(512);
ByteArrayOutputStream receiveStream = new ByteArrayOutputStream(512);
sendStream.write(0x0);
sendStream.write(OPCode);
sendStream.write(fileName.getBytes("US-ASCII"));
sendStream.write(0x0);
sendStream.write("netascii".getBytes("US-ASCII"));
sendStream.write(0x0);
DatagramSocket client = new DatagramSocket();
client.setSoTimeout(500);
send(sendStream.toByteArray(), client, Client.serverPort);
DatagramPacket receivedPacket = new DatagramPacket(receiveData, receiveData.length);
client.receive(receivedPacket);
int replyPort = receivedPacket.getPort();
String reply = new String(receivedPacket.getData(), StandardCharsets.US_ASCII).substring(0,receivedPacket.getLength());
receiveStream.reset();
receiveStream.write(reply.getBytes("US-ASCII"));
receiveData = receiveStream.toByteArray();
//debug("'" + new String(receiveData, "US-ASCII") + "'");
if(0x2 == OPCode)
{
int block = 0;
double sentData = 0;
while(receiveData[1] == 4)
{
if(receiveData[3] == block)
{
block++;
sendStream.reset();
sendStream.write(0x0);
sendStream.write(0x3);
sendStream.write(0x0);
sendStream.write(block);
while(sendStream.size() < 516)
{
int b;
b = fileStream.read();
if(b==-1)
{
break;
}
else
{
sendStream.write((byte) b);
}
}
sentData += sendStream.size() - 4;
System.out.print(String.format("\rStatus:\t\t%.2f%%", sentData/fileSize*100));
send(sendStream.toByteArray(), client, replyPort);
try
{
client.receive(receivedPacket);
reply = new String(receivedPacket.getData(), StandardCharsets.US_ASCII).substring(0,receivedPacket.getLength());
receiveStream.reset();
receiveStream.write(reply.getBytes("US-ASCII"));
receiveData = receiveStream.toByteArray();
replyPort = receivedPacket.getPort();
}
catch(SocketTimeoutException e)
{
System.out.println("Timed out, retrying...");
client.receive(receivedPacket);
reply = new String(receivedPacket.getData(), StandardCharsets.US_ASCII).substring(0,receivedPacket.getLength());
receiveStream.reset();
receiveStream.write(reply.getBytes("US-ASCII"));
receiveData = receiveStream.toByteArray();
replyPort = receivedPacket.getPort();
}
}
if(receiveData[3] == block-1)
{
System.out.println("Failed to reply to ACK");
send(sendStream.toByteArray(), client, replyPort);
client.setSoTimeout(500);
try
{
client.receive(receivedPacket);
reply = new String(receivedPacket.getData(), StandardCharsets.US_ASCII).substring(0,receivedPacket.getLength());
receiveStream.reset();
receiveStream.write(reply.getBytes("US-ASCII"));
receiveData = receiveStream.toByteArray();
replyPort = receivedPacket.getPort();
}
catch(SocketTimeoutException e)
{
System.out.println("Timed out, retrying...");
client.receive(receivedPacket);
reply = new String(receivedPacket.getData(), StandardCharsets.US_ASCII).substring(0,receivedPacket.getLength());
receiveStream.reset();
receiveStream.write(reply.getBytes("US-ASCII"));
receiveData = receiveStream.toByteArray();
replyPort = receivedPacket.getPort();
}
}
if(fileStream.available() < 1)
break;
}
debug("\nEnd of stream with reply:\n\t" + reply);
}
}
catch(Exception e)
{
System.out.println(e.toString());
}
return;
}
public static int getBlocks(String data)
{
int size = data.getBytes().length / 256;
if(data.getBytes().length % 256 > 0 && size > 1)
size++;
return size;
}
public static void send(byte[] response, DatagramSocket client, int port)
{
try
{
InetAddress IP = InetAddress.getByName(Client.serverAddress);
DatagramPacket packetToSend = new DatagramPacket(
response,
response.length,
IP,
port
);
client.send(packetToSend);
}
catch(Exception e)
{
System.out.println(e.toString());
}
}
public static void debug(String output)
{
System.out.println(output);
}
public static void debug(byte[] array)
{
String debug = "";
for(int x = 0; x < array.length; x++)
{
debug += " " + array[x];
}
System.out.println(debug);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment