/// <summary> /// Given an outgoing packet, return the server's response. /// </summary> /// <param name="toSend">The packet to send to the server.</param> /// <returns>The server's response to the given packet.</returns> private TFTPPacket ReceiveDatagram(TFTPPacket toSend) { byte[] bytes = toSend.GetBytes(); this._con.Send(bytes, bytes.Length); byte[] resp; try { resp = this._con.Receive(ref this._remoteEP); } catch (SocketException se) { throw new Exception("Failed to get a response from the server.", se); } short respCode = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(resp, 0)); if ((Opcode)respCode == Opcode.DATA) { short blockNum = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(resp, 2)); byte[] data = new byte[resp.Length - 4]; Array.Copy(resp, 4, data, 0, resp.Length - 4); return(new DataPacket(blockNum, data)); } else if ((Opcode)respCode == Opcode.ERROR) { short errNum = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(resp, 2)); string msg = BitConverter.ToString(resp, 4); return(new ErrorPacket(errNum, msg)); } else { throw new Exception(String.Format("Unexpected response from server: code {0}", respCode)); } }
/// <summary> /// Retrieve the client's target file and write it to the local directory. /// </summary> public void RetrieveAndWrite() { if (!Connected) { throw new Exception( String.Format("Remote connection is not initialized, so {0} cannot be retrieved.", this._fileName) ); } TFTPPacket datagram; if (this._reqType == RequestType.Error) { datagram = new RequestCorruptedPacket(this._fileName); } else { // implicitly with no error datagram = new RequestPacket(this._fileName); } TFTPPacket response = ReceiveDatagram(datagram); if (response.Opcode == Opcode.DATA) { HandleData((DataPacket)response); } else { // implicitly an error packet ReportError((ErrorPacket)response); } }