Skip to content
Snippets Groups Projects
Commit 5575b66c authored by joalhelk's avatar joalhelk
Browse files

rrq & wrq

parent f6f56aa3
No related branches found
No related tags found
No related merge requests found
Showing
with 187 additions and 44 deletions
No preview for this file type
......@@ -23,6 +23,7 @@ namespace FTPClient
TftpClient client = new TftpClient("test", 69);
client.InitializeAndRead("README");
client.SendWRQ("wrqFile");
client.SendRRQ("SmallText");
}
private static void FtpConversation()
......
......@@ -81,7 +81,8 @@ namespace FTPClient
socket.SendTo(packet, endpoint);
Console.WriteLine($"Sent Write Request for file: {writeFile}");
HandleWriteRequest();
if (!WaitAck()) return;
HandleWriteRequest(writeFile);
}
/// <summary>
......@@ -97,6 +98,16 @@ namespace FTPClient
HandleReadRequest();
}
private bool WaitAck()
{
byte[] buffer = new byte[512];
socket.ReceiveFrom(buffer, ref endpoint);
int opcode = buffer[0] | buffer[1] << 8;
if (opcode == (int)PACKET_TYPE.ACK) return true;
if (opcode == (int)PACKET_TYPE.ERROR) ReportError(buffer);
return false;
}
private byte[] MakeRequestPacket(PACKET_TYPE type)
{
byte[] packet = new byte[4 + filename.Length + MODE.Length];
......@@ -131,9 +142,47 @@ namespace FTPClient
endpoint = (EndPoint)ipEndp;
}
private void HandleWriteRequest()
private void HandleWriteRequest(string filename)
{
string path = Path.Combine(FILE_PATH, filename + ".txt");
using (FileStream fsSource = new FileStream(path,
FileMode.Open, FileAccess.Read))
{
// Read the source file into a byte array.
int numBytesToRead = (int)fsSource.Length;
int numBytesRead = 0;
int packetNumber = 1;
while (numBytesToRead > 0)
{
byte[] buffer = Create512Buffer((int)PACKET_TYPE.DATA);
buffer[2] = (byte)packetNumber;
buffer[3] = (byte)(packetNumber >> 8);
// Read may return anything from 0 to numBytesToRead.
int n = fsSource.Read(buffer, 4, 508);
socket.SendTo(buffer, endpoint);
// Break when the end of the file is reached.
if (n == 0)
break;
numBytesRead += n;
numBytesToRead -= n;
packetNumber += 1;
}
Console.WriteLine($"Sent {numBytesRead} bytes");
}
}
/// <summary>
/// Creates a data packet 512 bytes
/// </summary>
private static byte[] Create512Buffer(int opcode)
{
// TODO: Create handler
byte[] buffer = new byte[512];
buffer[0] = (byte)PACKET_TYPE.DATA;
buffer[1] = (byte)((int)PACKET_TYPE.DATA >> 8);
return buffer;
}
private void HandleReadRequest()
......@@ -167,29 +216,24 @@ namespace FTPClient
// CheckPacketNumber();
string path = Path.Combine(FILE_PATH, filename + ".txt");
if (!File.Exists(path))
// Create a file to write to.
using (StreamWriter sw = File.CreateText(path))
{
// Create a file to write to.
using (StreamWriter sw = File.CreateText(path))
bool conversation = ReadData(packet, sw);
while (conversation)
{
bool conversation = ReadData(packet, sw);
while (conversation)
{
byte[] buffer = new byte[512];
socket.ReceiveFrom(buffer, ref endpoint);
conversation = ReadData(buffer, sw);
}
Console.WriteLine("File received");
byte[] buffer = new byte[512];
socket.ReceiveFrom(buffer, ref endpoint);
conversation = ReadData(buffer, sw);
}
Console.WriteLine("File received");
}
else Console.WriteLine($"File: \"{path}\" already exists.");
}
/// <summary>
/// Read data from packet and write it to file
/// </summary>
/// <param name="packet">packet to read from</param>
/// <param name="sw">streamwriter to write with</param>
/// <returns>true if wasn't last packet (not below 508 bytes)</returns>
private bool ReadData(byte[] packet, StreamWriter sw)
{
......
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
......@@ -40,27 +40,23 @@ namespace TFTPServer
No_such_user
}
private static void ReadRequest(byte[] buffer, EndPoint remote)
/// <summary>
/// Sends a acknowledgement packet
/// </summary>
private static void SendAck(EndPoint remote)
{
string filename = string.Empty;
int index = 2;
do
{
filename += Convert.ToChar(buffer[index]);
index += 1;
} while (buffer[index] != 0);
Console.WriteLine($"Read request for file : {filename}");
byte[] packet = new byte[4];
packet[0] = (byte)PACKET_TYPE.ACK;
packet[1] = (byte)((int)PACKET_TYPE.ACK >> 8);
packet[2] = 0;
packet[3] = 0;
string file_path = Path.Combine(FILE_DIR, filename+".txt");
if (!String.IsNullOrEmpty(filename) && File.Exists(file_path)) {
SendData(file_path, remote);
} else
{
string message = "File not found.";
SendError(remote, (int)ERROR_CODE.File_not_found, message);
}
socket.SendTo(packet, remote);
}
/// <summary>
/// Sends the file data from path to client
/// </summary>
private static void SendData(string path, EndPoint remote)
{
using (FileStream fsSource = new FileStream(path,
......@@ -69,11 +65,13 @@ namespace TFTPServer
// Read the source file into a byte array.
int numBytesToRead = (int)fsSource.Length;
int numBytesRead = 0;
int packetNumber = 1;
while (numBytesToRead > 0)
{
byte[] buffer = Create512Buffer((int)PACKET_TYPE.DATA);
buffer[2] = (byte)blockNumber;
buffer[3] = (byte)(blockNumber >> 8);
buffer[2] = (byte)packetNumber;
buffer[3] = (byte)(packetNumber >> 8);
// Read may return anything from 0 to numBytesToRead.
int n = fsSource.Read(buffer, 4, 508);
......@@ -84,12 +82,15 @@ namespace TFTPServer
numBytesRead += n;
numBytesToRead -= n;
blockNumber += 1;
packetNumber += 1;
}
Console.WriteLine($"Sent {numBytesRead} bytes");
}
}
/// <summary>
/// Creates a data packet 512 bytes
/// </summary>
private static byte[] Create512Buffer(int opcode)
{
byte[] buffer = new byte[512];
......@@ -98,14 +99,17 @@ namespace TFTPServer
return buffer;
}
private static void SendError(EndPoint remote, int error_code, string message)
/// <summary>
/// Sends a error with given error code and message
/// </summary>
private static void SendError(EndPoint remote, ERROR_CODE error_code, string message)
{
byte[] messageBytes = Encoding.ASCII.GetBytes(message);
byte[] packet = new byte[4 + messageBytes.Length + 1];
packet[0] = (byte)PACKET_TYPE.ERROR;
packet[1] = (byte)((int)PACKET_TYPE.ERROR >> 8);
packet[2] = (byte)error_code;
packet[3] = (byte)(error_code >> 8);
packet[3] = (byte)((int)error_code >> 8);
int index = 4;
for(int i = 0; i < messageBytes.Length; i++)
......@@ -115,9 +119,103 @@ namespace TFTPServer
socket.SendTo(packet, remote);
}
private static void WriteRequest(byte[] buffer)
/// <summary>
/// Get filename from packet
/// </summary>
private static string FilenameFromPacket(byte[] packet)
{
throw new NotImplementedException();
string filename = String.Empty;
int index = 2;
do
{
filename += Convert.ToChar(packet[index]);
index += 1;
} while (packet[index] != 0);
return filename;
}
/// <summary>
/// Handles a read request from client
/// </summary>
private static void ReadRequest(byte[] buffer, EndPoint remote)
{
string filename = FilenameFromPacket(buffer);
Console.WriteLine($"Read request for file : {filename}");
string file_path = Path.Combine(FILE_DIR, filename + ".txt");
if (!String.IsNullOrEmpty(filename) && File.Exists(file_path))
{
SendData(file_path, remote);
}
else
{
string message = "File not found.";
SendError(remote, ERROR_CODE.File_not_found, message);
}
}
/// <summary>
/// Handles a write request from client
/// </summary>
private static void WriteRequest(byte[] buffer, EndPoint remote)
{
string filename = FilenameFromPacket(buffer);
string path = Path.Combine(FILE_DIR, filename + ".txt");
if(File.Exists(path)) {
string message = "File already exists";
SendError(remote, ERROR_CODE.File_already_exists, message);
return;
}
SendAck(remote);
HandleWRQ(remote, filename);
}
/// <summary>
/// Listens clients data packets
/// </summary>
private static void HandleWRQ(EndPoint remote, string filename)
{
string path = Path.Combine(FILE_DIR, filename + ".txt");
byte[] packet = new byte[512];
socket.ReceiveFrom(packet, ref remote);
int opcode = packet[0] | packet[1] << 8;
if (opcode == (int)PACKET_TYPE.DATA)
{
// Create a file to write to.
using (StreamWriter sw = File.CreateText(path))
{
bool conversation = ReadData(packet, sw);
while (conversation)
{
byte[] buffer = new byte[512];
socket.ReceiveFrom(buffer, ref remote);
conversation = ReadData(buffer, sw);
}
Console.WriteLine("File received");
}
}
}
/// <summary>
/// Read data from packet and write it to file
/// </summary>
/// <returns>true if wasn't last packet (not below 508 bytes)</returns>
private static bool ReadData(byte[] packet, StreamWriter sw)
{
string data = String.Empty;
for (int i = 4; i < packet.Length; i++)
{
if (packet[i] == 0) break;
data += Convert.ToChar(packet[i]);
}
sw.Write(data);
if (data.Length == 508) return true;
return false;
}
private static void ErrorResponse(byte[] buffer)
......@@ -146,12 +244,12 @@ namespace TFTPServer
}
catch (Exception ex)
{
Console.WriteLine("Virhe... " + ex.Message);
Console.WriteLine("Error... " + ex.Message);
Console.ReadKey();
return;
}
Console.WriteLine("Odotetaan asiakasta...");
Console.WriteLine("TFTP server up, listening for clients...");
while (!Console.KeyAvailable)
{
......@@ -166,7 +264,7 @@ namespace TFTPServer
ReadRequest(buffer, remote);
break;
case (int)PACKET_TYPE.WRQ:
WriteRequest(buffer);
WriteRequest(buffer, remote);
break;
case (int)PACKET_TYPE.DATA:
DataRequest(buffer);
......
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment